C++ 类可以包含一组类中的一个,这些类都继承自一个公共(public)类

标签 c++

在 C++ 中处理拥有另一个类实例所有权的类的方法是什么,其中该实例可能属于许多类,所有这些类都继承自一个公共(public)类?

例子:

class Item { //the common ancestor, which is never used directly
public:
  int size;
}

class ItemWidget: public Item { //possible class 1
public:
  int height;
  int width;
}

class ItemText: public Item { //possible class 2
  std::string text;
}

假设还有一个 Container 类,每个类都包含一个 Item,并且只有当他们从 Container 中取出 Item 时,人们才会对 Item 感兴趣。我们还假设 Items 仅在创建 Container 的同时创建,目的是将它们放入 Container。

有哪些不同的构造方法?我们可以在 Container 中为包含的 Item 创建一个指针,然后将参数传递给 Container 的构造函数,以确定要在哪种 Item 上调用 new,这会将 Items 全部放入堆中。有没有一种方法可以将 Item 与 Container 一起存储在堆栈中,这有什么好处吗?

如果 Container 和 Items 是不可变的,我们在创建时就知道它们的一切,并且永远不会改变它们,这会有什么不同吗?

最佳答案

正确的解决方案如下:

class Container {
public:
    /* ctor, accessors */
private:
    std::unique_ptr<Item> item;
};

如果你有一个旧的编译器,你可以使用 std::auto_ptr 代替。

智能指针确保容器对项目的严格所有权。 (你也可以把它变成一个普通的指针,然后卷起你自己的析构函数/赋值操作/复制构造函数/移动构造函数/移动赋值操作/等等,但是 unique_ptr 已经完成了这一切,所以...)

为什么这里要用指针,而不是普通的组合?

因为如果你进行组合,那么你必须知道将要组合的确切类。你不能引入多态性。此外,所有 Container 对象的大小必须相同,Item 的派生类的大小可能不同。

如果您迫切需要作曲?

那么您需要与存储的项目一样多的 Container 变体,因为每个这样的 Container 都有不同的大小,所以它是一个不同的类。你最好的镜头是:

struct IContainer {
    virtual Item& getItem() = 0;
};

template<typename ItemType>
struct Container : IContainer {
    virtual Item& getItem() {
        return m_item;
    }
private:
    ItemType m_item;
};

关于C++ 类可以包含一组类中的一个,这些类都继承自一个公共(public)类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7277490/

相关文章:

c++ - 抛出 io_service::run() 后,boost::asio 在解析器服务析构函数中挂起

C++ 用静态内联声明模板函数有意义吗?

python - 使用可用库的子集为 iOS 编译 OpenCV 3.1.0

c++ - 在 box2d 中操纵 Sprite 运动

c++ - 使用默认值初始化 unique_ptr 的 vector (nullptr?)

c++ - 动态创建的数组

具有 4 字节对齐缓冲区的 C++ `std::string` 类容器

c# - 是否可以在非托管 VC++ 应用程序中使用使用 C# 创建的 DLL?

c++ - C 预处理器中是否存在逻辑短路?

c++ - atomic<T*> 总是无锁的吗?