我有一个继承层次结构,其中 A 是抽象基类,B 和 C 是多态子类。
我希望在堆上有一个向量类数据成员,它可以包含 B 和 C 对象。
所以在头文件中我有我的
vector<A*> polymorphicobjs;
在我试图做的构造函数中:
polymorphicobjs = new vector<A>();
但显然这行不通。我如何实现这一目标?
我有一个继承层次结构,其中 A 是抽象基类,B 和 C 是多态子类。
我希望在堆上有一个向量类数据成员,它可以包含 B 和 C 对象。
所以在头文件中我有我的
vector<A*> polymorphicobjs;
在我试图做的构造函数中:
polymorphicobjs = new vector<A>();
但显然这行不通。我如何实现这一目标?
您不必担心保留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>());
如果 C++11 是一个选项或增强选项,我真的建议你坚持使用标准的 shared_pointers。
您的基本问题是您声明了 a vector
of 指针而不是指向 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>());
你为什么要做一个new
?
这一行:
vector<A*> polymorphicobjs;
已经初始化您的vector
...之后,您可以执行以下操作:
polymorphicobjs.push_back( an_object );
如果您真的想把它放在堆上,请将您的声明更改为:
vector<A*>* polymorphicobjs;
// ^
但是我觉得没必要...
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.
你不需要新的向量。我怀疑你来自 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;
}
智能指针向量会更好..