C++ 使用堆栈分配的对象以向量形式存储异构对象

C++ 使用堆栈分配的对象以向量形式存储异构对象,c++,inheritance,vector,polymorphism,dynamic-memory-allocation,C++,Inheritance,Vector,Polymorphism,Dynamic Memory Allocation,使用堆栈分配的对象在异构向量中存储对象 你好, 假设我有一个抽象类CA,派生成CA1、CA2,也许还有其他类 我想把这些派生类型的对象放到一个向量中,我把它嵌入到一个类CB中。为了获得正确的多态性,我需要存储指针向量: class CB { std::vector <CA*> v; }; 如何以一种简单的方式编写方法void CB::Store(const CA&),使存储的对象在原始对象被销毁时仍然存在(在上面的简单示例中没有发生这种情况) 我的问题是,在向量中复制对象的

使用堆栈分配的对象在异构向量中存储对象

你好,

假设我有一个抽象类CA,派生成CA1、CA2,也许还有其他类

我想把这些派生类型的对象放到一个向量中,我把它嵌入到一个类CB中。为了获得正确的多态性,我需要存储指针向量:

class CB
{
    std::vector <CA*> v;
};
如何以一种简单的方式编写方法
void CB::Store(const CA&)
,使存储的对象在原始对象被销毁时仍然存在(在上面的简单示例中没有发生这种情况)

我的问题是,在向量中复制对象的地址之前,我需要先复制堆上的对象,但是如何创建派生类型的对象呢?当然,我可以使用RTTI,搜索所有可能的类型,创建并分配指针,并在将对象推入向量之前将其复制(通过适当的强制转换)到分配的空间中。但这似乎很复杂,不是吗

有没有更简单的方法


(并且不在主类中使用动态分配!)

听起来您需要在抽象类中使用clone()函数,派生类将实现该函数

class CA
{
   public:
   virtual ~CA() {}
   virtual CA* clone() const = 0;
}

class CA1 : public CA
{ 
    public:
    virtual CA *clone() const
    {
       return new CA1(*this);
    }
};

通常,您将提供克隆功能:

int main()
{
    CB b;
    CA1 a1;
    CA2 a2;
    b.Store( a1 );
    b.Store( a2 );
}
struct CA
{
    virtual CA *clone(void) const = 0;
    virtual ~CA() {} // And so on for base classes.
}

struct CA1 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA1(*this);
    }
}

struct CA2 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA2(*this);
    }
}
这称为,您可以在运行时构造对象的副本:

void CB::Store(const CA& pObject)
{
    CA *cloned = pObject.clone();
}
你应该考虑使用图书馆。您的代码是:

boost::ptr_vector<CA> objects;

void CB::Store(const CA& pObject)
{
    objects.push_back(pObject->clone());
}
boost::ptr_矢量对象;
无效CB::存储(常量CA和POObject)
{
对象。向后推(pObject->clone());
}

现在您不需要自己管理内存。库也尊重克隆函数,并在复制对象时调用它

一种可能是根据其参数的类型对存储进行模板化:

class CB
{
public:
    template<class T>
    void Store(const T& t)
    {
         v.push_back(new T(t));
    }

private:
    std::vector <CA*> v;
};
但这并不是:

CA1 a1;
CA* a = &a1;
b.Store(*a); //Ouch! this creates a new CA, not a CA1

向CA提供受保护的副本可以防止此类误用。然而,如果我们进一步研究CA1亚类,问题又回来了。

主要是,他说。我想他希望尽可能地把繁重的工作(动态分配)结束并远离客户。我想你错过了CA、CA1和CA2之间的继承关系虚拟析构函数在哪里?哎呀,哈哈。继承对我来说是愚蠢的。我故意留下虚拟析构函数之类的细节,因为这会妨碍答案。非常好的解决方案,谢谢,我今天学到了一些东西!我将查看Boost指针库。我认为您错过了CA和CA1之间的继承关系…以及虚拟析构函数和“public:;-)
CA1 a1;
CA* a = &a1;
b.Store(*a); //Ouch! this creates a new CA, not a CA1