下面的问题对我来说有点难以表述,但请耐心等待,并告诉我是否可以帮助解决问题。
我正在编写 3D 形状的通用模拟。我正在使用基类:
class Shape{
public:
...
virtual double return_volume() =0;
private:
vector<double> coordinates;
...
};
现在,由于我不知道用户会选择什么形状,所以我从中派生出几个类。 (例如:球体、立方体、四面体等)
到目前为止,一切都很好。 主要问题来自于我有一个 Controller 类,它启动并操作模拟。作为私有(private)成员,它应该具有多个形状的 vector (所有形状相同。例如:15 个球体,或 10 个立方体等)
class SimulationControl{
public:
void runsimulation();
private:
vector<Shape> all_shapes;
...
};
我想简单地使用非默认构造函数初始化这个私有(private)成员。 现在,在我知道我做了什么之前,Eclipse 已经告诉我“类型‘Shape’必须实现继承的纯虚拟方法‘Shape::return_volume’”
当然,我理解错误消息和我的错误,但我仍然不明白如何解决它。
我希望能够做的是保留 vector 的类型未定义,然后当我知道用户选择哪种类型的模拟时,在运行时使用正确的派生类通过构造函数简单地创建它。
是否有可能做到这一点?谢谢
最佳答案
我不会跟风建议在容器中使用指针,无论是聪明的还是愚蠢的。这是使用 PIMPL idiom 的绝佳机会.
这个想法是,该类只是实际实现的包装器,并在调用它时调用指向另一个对象的指针。包装器中包含的指针可以是多态的,以便它可以实现它认为合适的函数。
class Shape{
public:
Shape() { pImpl = NULL; }
Shape(const Shape& from) { pImpl = from.pImpl->clone(); }
~Shape() { delete pImpl; }
Shape& operator=(const Shape& from) { pImpl = from.pImpl->clone(); }
...
double return_volume() { return pImpl->return_volume(); }
private:
ShapeImpl * pImpl;
...
};
class ShapeImpl{
public:
...
virtual ShapeImpl* clone() const =0;
virtual double return_volume() =0;
private:
vector<double> coordinates;
...
};
因为 Shape
类包含一个指针,您需要实现 rule of three并创建一个析构函数、复制构造函数和 operator=
。拷贝的默认值肯定会做错误的事情 - 它们只会复制指针值,而不会创建 pimpl 对象的新拷贝来与之配合。由于 vector
围绕这些函数复制元素,因此肯定会被调用。
关于c++ - 如何在运行时决定将哪个派生类用作 C++ 中的私有(private)类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15046584/