这是代码:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class A {
public:
virtual const string f() const { return "A"; }
};
class B : public A {
public:
const string f() const { return "B"; }
};
int main(int ac, char** av) {
vector<A> v;
v.push_back(B());
cout << v.at(0).f() << endl;
return 0;
}
预期结果为B
,但它是A
。据我所知,对象切片正在发生。怎么避免呢?我应该在vector
而不是对象实例中存储指针吗?这是唯一的选择吗?
答案 0 :(得分:12)
你需要存储指针。如果这些引用了动态分配的对象,请使用智能指针。
答案 1 :(得分:12)
从最简单,最复杂(但最好)订购。
解决方案1:
vector<B> v;
v.push_back(B());
cout << v.at(0).f() << endl;
解决方案2:
vector<A*> v;
v.push_back(new B());
cout << v.at(0)->f() << endl;
while(!v.empty()) { delete v.back(); v.pop_back(); }
解决方案3:
vector<boost::shared_ptr<A>> v;
v.push_back(boost::make_shared<B>());
cout << v.at(0)->f() << endl;
如果您不希望切片发生,您需要考虑到不同对象可能具有不同大小的事实 - 您需要一个可以使用可变大小的解决方案 - 这使得在堆上存储必须的。
答案 2 :(得分:3)
好吧,在您的代码中,您可以使用B的向量。请注意,只有通过指针或引用调用时,才会正确调度虚函数。但是,假设您确实希望向量包含A和B对象,则需要将其作为A指针的向量,并动态创建A和B对象。