我想将某些派生类的对象存储为另一个对象的属性。

对我来说,问题是要知道要存储的对象的大小,因为它可以是给定基类的任何派生类。我不能只是为基类的对象分配内存,因为它较小。我想, 类型 操作员也只会给出基类的大小,对吗?

这是我的示例代码。请参阅评论以理解我的意思。请原谅我

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构造函数,至少总记忆消耗不会上升)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top