3

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

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

所以在头文件中我有我的

vector<A*> polymorphicobjs;

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

polymorphicobjs = new vector<A>();

但显然这行不通。我如何实现这一目标?

4

5 回答 5

5

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

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

现在您可以很容易地将多态对象存储在向量中(其中B是 的子类A):

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>());
于 2013-09-26T12:26:26.817 回答
2

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

您的基本问题是您声明了 a vectorof 指针而不是指向 avector

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>());
于 2013-09-25T16:15:18.560 回答
1

你为什么要做一个new

这一行:

vector<A*> polymorphicobjs;

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

polymorphicobjs.push_back( an_object );

如果您真的想把它放在堆上,请将您的声明更改为:

vector<A*>* polymorphicobjs;
//        ^

但是我觉得没必要...

于 2013-09-25T16:04:09.577 回答
0

You can achieve this as you can with any other type:

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

If vector<A*> confuses you try to use this:

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

So problem that your polymorphicobjs is a vector of pointers, not pointer to such vector.

于 2013-09-25T16:10:23.137 回答
0

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

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

polymorphicobjs.push_back(new B());

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

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

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

智能指针向量会更好..

于 2013-09-25T16:21:24.043 回答