我尝试将对象添加到“content”向量中,并对所有对象使用show()。 但是作为“Base”的子(A,B)的对象表现得像“Base”类型, 什么不是我的意图。看起来,我试图使用虚函数,但它不起作用。
我希望代码能够说明问题。
class Base {
public:
virtual void show() { cout << "Base "; }
};
class A : public Base {
public:
virtual void show() { cout << "A "; }
};
class B : public Base {
public:
virtual void show() { cout << "B"; }
};
vector<Base> content;
void add(Base &o) {
content.push_back(o);
}
A test1;
B test2;
add(test1);
add(test2);
for (size_t i = 0; i < content.size(); i++) {
collection[i].show(); // output is: Base Base instead of A B
}
提前致谢。
答案 0 :(得分:3)
你所拥有的是基地的载体 向向量添加somthing时,它会被复制到向量中但只复制了baser部分。因此,您将丢失所有已公开的信息。
这被称为切片问题。
一个简单的解决方案是将指针存储在向量中。
答案 1 :(得分:2)
正如其他人所说,你正在经历切片。 vector
存储Base
,任何派生的信息都会被删除。
用指针缓解这一点:
std::vector<Base*> v;
v.push_back(new A);
v.push_back(new B);
现在的问题是释放你的资源。在向量超出范围之前,您需要遍历它并删除每个元素。更糟糕的问题是例外情况。
如果在向量的生命周期中的任何时刻,如果抛出异常,它将展开堆栈,在某个时刻释放向量中的所有指针;一个巨大的记忆泄漏。
如果您使用更专用的容器,则可以避免此问题。要么自己写一个(当然不推荐),要么使用boost pointer containers。
答案 2 :(得分:1)
STL容器存储值对象。你在这里所谓的切片。
答案 3 :(得分:0)
vector<Base*> content; // <<
void add(Base *o) { // <<
content.push_back(o);
}
A test1;
B test2;
add(&test1); // <<
add(&test2); // <<
for (size_t i = 0; i < content.size(); i++) {
collection[i]->show(); // <<
}
答案 4 :(得分:0)
您必须使用vector<Base*>
,因为目前您添加的对象将复制到Base
类型的新对象中。