C++ 创建一个抽象类型的对象 class

C++ make an object whose type is an abstract class

我正在尝试制作一个类似于 Java 的 swing 的系统,其中有一个 window,并且 window 有多个组件,例如标签(text/images), Text Boxes, Check Boxes等。swing的工作方式是有一个Component class,它是抽象的,它有一个抽象的paint方法,绘制组件,以及其他一些方法。实际的 window (JFrame) 有一个 window 中所有组件的列表(排序)。这些组件的实际类型未知,但它们都扩展了 Component class.

我的Windowclass:

class Window {
public:
    ...
    template<typename T, typename std::enable_if<std::is_base_of<Component, T>::value>::type* = nullptr> T addComponent(T component);
private:
    ...
    std::vector<Component> components;
    ...
};

Component:

class Component {
public:
    ...
    virtual void paintComponent() = 0;
    ...
};

沿线某处,此代码称为:

for each (Component c in components) {
    c.paintComponent();
}

但是,我不能创建 Component 类型的对象,因为它是抽象的,尽管实际对象是 扩展 Component 的其他类型并拥有自己的 paintComponent() 方法。对于方法 (Window::addComponent()),我可以使用

template<typename T, typename std::enable_if<std::is_base_of<Component, T>::value>::type* = nullptr> T

但是,这不适用于变量。

所以,我的问题是,如何制作抽象类型的对象,即如何制作 Component 对象(或扩展对象)组件,实际类型未知)?

提前致谢!

在这样的系统中,LabelCheckBoxTextBox 等类型是独立的 classes 派生自 Component class。因此,如果您想要类似的行为,您需要实现新的 classes 并从 Component class 派生它们。您还需要覆盖虚拟功能。

您不能实例化抽象类型 class。您必须通过指针来引用它。这将迫使您进行手动内存管理。所以使用像 shared_ptr or unique_ptr 这样的智能指针可以帮助减少头痛。使用指针会使你的矢量看起来像这样

std::vector<Component*> components;
//                   ^ Indicates pointer

然后在你的循环中你会这样称呼它

p->paintComponent();

这样您就可以将 Component 用于派生自它的任何类型。

另外,如果要像这样使用 Component,它应该有一个虚拟析构函数。如果它通过指向 Component 的指针删除,这将确保调用正确的析构函数。这将使析构函数声明看起来像这样

virtual ~Component() { }