4

ヘッダー ファイルに抽象クラスEngine3Dとその構造体 (Vector3Dなど) があります。

これで、そのクラスの実装ができましたConcreteEngine3D : Engine3D。また、そのような他のクラスには、ConcreteVector3D : Vector3D内部で使用される追加のメンバーとメソッドがあります(この例のために、 and とConcreteEngine3Dしましょう)。float lengthcalculateLength()

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)から継承されるコンストラクターの内部で呼び出します(これは、からのフィールドを持つ新しいオブジェクトを作成し、それを返します)。Engine3DConcreteEngine3DConcreteVector3DVector3D

もちろん、そのコードは機能しません:

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 を使用したくありませんConcreteEngine3DVector3D最初のコードで書いたように、「ユーザー」が作成できるようにしたいと思います。

4

2 に答える 2

4

具象クラスのコンストラクターを直接呼び出す必要がないように、抽象ファクトリ パターンを使用してオブジェクトをインスタンス化する必要があるようです。次に、インターフェイスを実装する具象型を変更する場合は、抽象化ファクトリの別の実装にリンクするか、実行時に適切なファクトリ実装を選択するだけで済みます。

編集:「ファクトリを使用したくない」を逃しました... とにかく、コンストラクターはインスタンス化した型を返すため、何らかのリダイレクトが必要になります。あなたが得ることができる最も近いのは、おそらくVector3Dへのポインタを返すクラスVector3Dへの静的ファクトリメソッド「作成」を作成することですが、具体的な実装クラスのインスタンスを内部的に作成します。その場合、Vector3D のコンストラクターを非公開にして、「間違った方法」でベクターを作成しないようにすることをお勧めします。

于 2012-07-01T17:53:13.990 に答える
0

アンドリュー・トマゾス、不明確な文章について-申し訳ありません:/

main.cpp を変更しないと達成できないという点で、Captain Giraffe に同意する必要があります。少し変更したファクトリーパターンを使用しました:

Engine3D::convert() を呼び出して結果を返す Vector3D::create() 静的関数を作成する必要がありました。したがって、コードは次のようになります。

#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
    engine = new ConcreteEngine3D();
    Vector3D vector = Vector3D::create(engine, 10, 5, 2);
}

Vector3D::create の内部:

return engine->convert(new Vector3D(x,y,z));

これは ConcreteVector3D を生成します (エンジンのタイプが ConcreteEngine3D であるため)。

main.cpp の最小限の変更、許容範囲 (main.cpp で ConcreteVector3D が言及されていない)。

もう一度、助けてくれてありがとう、皆さん!:-)

于 2012-07-01T21:01:23.137 に答える