在 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/