在堆上创建多态对象的数据成员向量?

时间:2013-09-25 16:01:36

标签: c++ vector polymorphism

我有一个继承层次结构,其中A是抽象基类,B和C是多态子。

我希望在堆上有一个vector类数据成员,它可以包含B和C对象。

所以在头文件中我有我的

vector<A*> polymorphicobjs;

并在我试图做的构造函数中:

polymorphicobjs = new vector<A>();

但显然这不起作用。我如何实现这一目标?

5 个答案:

答案 0 :(得分:5)

你不应该担心保留std::vector原始指针。稍后确保您在正确的时间删除对象会给您带来很多麻烦。你应该做的是存储一个“托管”多态对象的容器(使用smart pointers)。声明你的向量:

std::vector<std::unique_ptr<A>> polymorphicobjs;

现在你可以很容易地在向量中存储多态对象(其中BA的子类):

polymorphicobjs.push_back(std::unique_ptr<B>(new B));

有了这个,你不必担心在向量中的对象上调用delete。只要你“放开”向量(例如,当它超出你的函数中的范围,或者如果它是一个类成员就自动被破坏),对象将被删除。向量唯一拥有对象。

但我需要与其他代码共享对象?

如果是这种情况,则std::unique_ptr不是正确的选择。我们可以使用std::shared_ptr

表示对象共享
std::vector<std::shared_ptr<A>> polymorphicobjs;
// [...]
polymorphicobjs.push_back(std::make_shared<B>());

为什么push_back对于唯一和共享看起来有所不同?

因为C ++ 14还没有出来。如果你足够幸运地使用足够新的编译器(前沿clang / gcc / VS2013),那么唯一版本看起来非常相似:

// C++14
std::vector<std::unique_ptr<A>> polymorphicobjs;
// [...]
polymorphicobjs.push_back(std::make_unique<B>());

答案 1 :(得分:2)

我真的建议你坚持使用标准的shared_pointers,如果C ++ 11是一个选项或者是提升选项。

您的基本问题是您声明了vector指针而非指向vector的指针

vector<T*> vec1;// a vector of pointers
vec1.push_back(new T); // add a pointer to our vector

vector<T*>* vec2; //a pointer to a vector of pointers
vec2 = new vector<T>; // create the vector on the heap
vec2->push_back(new T); // add pointer.

正如我所说,这很可能不是你想要的。你应该使用智能指针。

vector<std::shared_ptr<A>> vec;
vec.push_back(std::make_shared<B>());

答案 2 :(得分:1)

你为什么要做new

这一行:

vector<A*> polymorphicobjs;

已初始化您的vector ...之后,您可以执行以下操作:

polymorphicobjs.push_back( an_object );

如果您确实想将它放在堆上,请将声明更改为:

vector<A*>* polymorphicobjs;
//        ^

但我认为没有必要......

答案 3 :(得分:0)

您可以使用任何其他类型实现此目的:

int i = new int; // Error
int *pi = new int; // works!

如果vector<A*>混淆,请尝试使用此功能:

typedef vector<A*> vectorOfA;
vectorOfA v = new vectorOfA; // Error
...                          // guess what will work?

问题是你的polymorphicobjs是一个指针向量,而不是指向这种向量的指针。

答案 4 :(得分:0)

您不需要新建矢量。我怀疑你是来自Java,一切都需要新的。 C ++是不同的。只需在课程中使用vector<A*> polymorphicobjs即可创建一个。{1}}。无论如何,向量将其数据元素存储在堆上。如果需要,可以在类的构造函数的初始化列表中调用其构造函数。否则它默认为空矢量。

创建新对象并将它们放在向量中:

polymorphicobjs.push_back(new B());

这将向您的向量添加一个新的B对象。

您需要在某些时候删除它们(例如析构函数)。

for (vector<A*>::iterator it = polymorphicobjs.begin(), end_it = polymorphicobjs.end(); it != end_it; ++it)
{
    delete *it;
}

智能指针的向量会更好..

相关问题