我有一个继承层次结构,其中A是抽象基类,B和C是多态子。
我希望在堆上有一个vector类数据成员,它可以包含B和C对象。
所以在头文件中我有我的
vector<A*> polymorphicobjs;
并在我试图做的构造函数中:
polymorphicobjs = new vector<A>();
但显然这不起作用。我如何实现这一目标?
答案 0 :(得分:5)
你不应该担心保留std::vector
原始指针。稍后确保您在正确的时间删除对象会给您带来很多麻烦。你应该做的是存储一个“托管”多态对象的容器(使用smart pointers)。声明你的向量:
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>());
答案 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;
}
智能指针的向量会更好..