4

我有一个抽象类Engine3D,它的结构(Vector3D等)在头文件中。

现在,我有该类的实现,ConcreteEngine3D : Engine3D. 此外,我还有其他类似的类ConcreteVector3D : Vector3D具有将在内部使用的其他成员和方法ConcreteEngine3D(为了这个示例,假设它是float lengthand 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来改变它的类型?

例如Vector3D* Engine3D::convert(Vector3D v)在构造函数内部调用,它将继承自Engine3Din 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)or行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!
}

另外,我不想在Engine3Dor中使用工厂ConcreteEngine3D。我想允许“用户”Vector3D按照我在第一个代码中编写的方式创建。

4

2 回答 2

4

听起来您想使用抽象工厂模式来实例化您的对象,这样您就不必直接调用具体类的构造函数。然后,如果您想更改实现接口的具体类型,您只需要链接到抽象工厂的不同实现,或者在运行时选择合适的工厂实现。

编辑:错过了“不想使用工厂”...无论如何,您将需要某种重定向,因为构造函数将返回您实例化的类型。您可以获得的最接近的可能是为类 Vector3D 创建一个静态工厂方法“create”,该方法返回一个指向 Vector3D 的指针,但在内部创建一个具体实现类的实例。如果您这样做,最好将 Vector3D 的构造函数设为私有,以防止以“错误的方式”创建向量。

于 2012-07-01T17:53:13.990 回答
0

Andrew Tomazos,关于不清楚的文字 - 抱歉:/

我必须同意 Giraffe 船长的观点,即如果不对main.cpp进行任何更改,我就无法实现它。我使用了稍微修改的工厂模式:

我必须制作 Vector3D::create() 静态函数,它将调用 Engine3D::convert() 并返回它的结果。所以代码将是:

#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 回答