ヘッダー ファイルに抽象クラスEngine3D
とその構造体 (Vector3D
など) があります。
これで、そのクラスの実装ができましたConcreteEngine3D : Engine3D
。また、そのような他のクラスには、ConcreteVector3D : Vector3D
内部で使用される追加のメンバーとメソッドがあります(この例のために、 and とConcreteEngine3D
しましょう)。float length
calculateLength()
main.cpp には次のコードがあります。
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2);
}
vector
変数を typeにしたいConcreteVector3D*
。
でその型が必要になりますConcreteEngine3D
が、 main.cpp では、それがその型であることさえ知らず、 のような拡張フィールドを使用する必要はありませんlength
。また、main.cpp では特に ConcreteEngine3D.h (Engine3D.h のみ) からのものを使用することはできません。これは柔軟なためnew ConcreteEngine3D()
です。
上記のコードや の元のヘッダーを変更したくありませんEngine3D
。
のコンストラクターでは、Vector3D
常にEngine3D
オブジェクトへのポインターを配置します (ここでConcreteEngine3D
型を指定します)。
のコンストラクターで何かをして、Vector3D
その型を変更することはできますか?
たとえば、 inVector3D* Engine3D::convert(Vector3D v)
から継承されるコンストラクターの内部で呼び出します(これは、からのフィールドを持つ新しいオブジェクトを作成し、それを返します)。Engine3D
ConcreteEngine3D
ConcreteVector3D
Vector3D
もちろん、そのコードは機能しません:
Vector3D::Vector3D(Engine3D *engine){
//how to 'return' or 'convert' the type to the one that returns engine->convert(this);
}
したがって、基本的には、以下のコードの効果を得たいのですが、行vector = engine->convert(vector)
またはVector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2)
.
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2); //produces Vector3D, not ConcreteVector3D
vector = engine->convert(vector); //cannot be here! but creates the right object
Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2); //also creates rights object, but cannot be here!
}
Engine3D
また、 orで factory を使用したくありませんConcreteEngine3D
。Vector3D
最初のコードで書いたように、「ユーザー」が作成できるようにしたいと思います。