如何在运行时决定将哪个派生类用作C++中的私有类成员
How can I decide at runtime which derived class to use as a private class member in C++?
下面的问题对我来说有点难以表述,但请耐心等待,如果我能帮助澄清任何问题,请告诉我。
我正在为三维形状编写一个通用模拟。我正在使用一个基类:
class Shape{
public:
...
virtual double return_volume() =0;
private:
vector<double> coordinates;
...
};
现在,由于我不知道用户会选择什么形状,我从中派生了几个类。(例如:球体、立方体、四面体等)
到目前为止,一切都很好。主要的问题是我有一个Controller类,它启动并操作模拟。作为私人成员,它应该有多个形状的矢量(都是同一类型。例如:15个球体或10个立方体等)
class SimulationControl{
public:
void runsimulation();
private:
vector<Shape> all_shapes;
...
};
我想简单地用一个非默认构造函数初始化这个私有成员。现在,在我知道我做了什么之前,Eclipse已经告诉我"类型‘Shape’必须实现继承的纯虚拟方法‘Shape::return_volume’"
当然,我理解错误信息和我的错误,但我仍然不明白如何解决它
我希望能够做的是不定义向量的类型,然后在运行时通过具有正确派生类的构造函数简单地创建它,当我知道用户选择了哪种类型的模拟时。
有可能做到这一点吗?感谢
我不会赶时髦,建议在容器中使用指针,无论是聪明的还是愚蠢的。这是使用PIMPL习语的绝佳机会。
其思想是,类只是实际实现的包装器,并在对其进行调用时调用指向另一个对象的指针。包装器中包含的指针可以是多态的,这样它就可以实现它认为合适的函数。
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
类包含一个指针,所以您需要实现三规则并创建一个析构函数、复制构造函数和operator=
。副本的默认值肯定会做错误的事情——它们只会复制指针值,而不会创建皮条对象的新副本。由于vector
复制了这些函数周围的元素,因此这些函数肯定会被调用。
使用(智能)指针。
您无法实例化抽象类,即使可以,也可能不是您想要的,因为您将无法创建这些形状的别名。
您应该将SimulationControl
类的定义更改为与此更相似的内容(假设您的形状在此共享所有权-如果SimulationControl
是您的形状的唯一所有者,请使用unique_ptr
而不是shared_ptr
):
#include <memory>
class SimulationControl {
public:
void runsimulation();
private:
std::vector<std::shared_ptr<Shape>> all_shapes;
...
};
然后,您可以创建形状的实例,并将它们添加到all_shapes
集合中,如下所示(假设MyShape
是从Shape
派生的一个具体的、默认的可构造类):
std::shared_ptr<MyShape> pShape = std::make_shared<MyShape>();
pShape->set_vertices(...); // I guess the class will have a member function
// that allows setting the shape's vertices...
all_shapes.push_back(pShape);
只能通过指针或引用进行多态性。尝试使用vector<Shape*>
。
既然你正在使用指针,你就必须为它们管理内存,但这是另一组问题。如果可以的话,试着使用智能指针,如果不能,请非常小心。如果您正在使用C++11,std::vector<std::unique_ptr<Shape>>
可能适合您。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- 多成员Constexpr结构初始化
- 我们可以访问一个不存在的联盟的成员吗