如何为我不知道的对象分配内存? C ++
-
29-09-2019 - |
题
我想将某些派生类的对象存储为另一个对象的属性。
对我来说,问题是要知道要存储的对象的大小,因为它可以是给定基类的任何派生类。我不能只是为基类的对象分配内存,因为它较小。我想, 类型 操作员也只会给出基类的大小,对吗?
这是我的示例代码。请参阅评论以理解我的意思。请原谅我
BaseA {};
DerivedA1 : BaseA {public: void property() { cout << 1; }};
DerivedA2 : BaseA {public: void property() { cout << 2; }};
// etc. - several derived classes.
BaseB // Contains (or links to) an instance of class derived from BaseA.
{
public:
BaseA * instanceA;
BaseB (BaseA instanceAX)
{
// ??? => How to allocate memory for the object
// I don't know the real type of?
instanceA = new BaseA (instanceAX);
}
BaseB (BaseA instanceAX) { delete instanceA; }
};
main()
{
DerivedA1 instanceA1;
BaseB instanceB (instanceA1);
// Use "property" regardless of which derived class it belongs to.
instanceB.instanceA->property();
}
我可以存储一个指针而不是对象本身,这会更容易。但是我不确定我是否想依靠呼叫者来保留实例生命的属性对象 Instanceb.
谢谢!
解决方案
好吧,首先,由于您按价值传递给Basea,而不是通过参考或指针传递,因此您确实知道类型。是巴斯阿。将baseb复制到basea中,并将Basea副本发送到该功能。 baseb中的任何额外数据都不包含在instanceax中。这称为“切片”。
但是,要回答您的问题,您根本不这样做。如果要以这种方式工作,则需要在baseB类中的clone()函数。另外,您可以设计一个可以为您克隆实例的智能指针或其他对象。如果您在comp.lang.c ++以及clone()上搜索我的名字,您可能会遇到有关后一种想法的讨论。
克隆函数当然是一个虚拟函数,它返回当前对象的副本:
struct BaseA
{
virtual BaseA* clone() const = 0;
};
struct BaseB : BaseA
{
BaseB* clone() const { return new BaseB(*this); }
};
其他提示
我看到了两种可能性。
给
BaseA
纯粹的虚拟成员函数,也许称为clone
, ,这负责生成调用实例的副本。然后是BaseB
可能会变成BaseB (BaseA const &instanceAX) { instanceA = instanceAX.clone (); }
您也可以避免将原始指针传递到周围并使用
boost::shared_ptr
反而。这样,由于它是参考计数,您的呼叫者不会过早破坏BaseA
用于构建的推导BaseB
. 。你必须调整BaseA * instanceA;
读书boost::shared_ptr <BaseA> instanceA;
然后BaseB
的构造函数可能看起来像:BaseB (boost::shared_ptr <BaseA> a) : instanceA (a) { }
第一个剥夺的问题是,某些继承的客户程序员,说 DerivedA1
可能会忘记实施 clone
在他的派生中。第二个剥夺的主要问题是要求每个用户 BaseB
要在堆上分配属性对象(因为您正在内部制作副本 BaseB
无论如何,s构造函数,至少总记忆消耗不会上升)