我有以下两个类,一个继承自另一个
Class A{
void print(){cout << "A" << endl;}
}
Class B : A{
void print(){cout << "B" << endl;}
}
Class C : A{
void print(){cout << "C" << endl;}
}
然后在另一个课程中我有以下内容:
vector<A> things;
if (..)
things.push_back(C());
else if (..)
things.push_back(B());
things[0].print();
这总是打印A
我希望它能打印B或C,具体取决于我添加到矢量中的东西
我该怎么办?
我已经尝试过抽象,但我不完全确定如何在C ++中使用它并且它一直没有为我工作
答案 0 :(得分:8)
1)您需要在A类中将print()声明为虚拟。
2)你的矢量不正确 - 你不能在那里存储实际的A类物体;你将需要存储指向它们的指针以获得正确的行为(并且你必须在以后清理它们)和/或使用类似boost :: shared_ptr的东西。
答案 1 :(得分:8)
如上所述,您需要virtual
函数来启用多态行为,并且不能直接按vector
中的值存储类。
当您使用std::vector<A>
时,您将按值存储,从而存储您添加的对象,例如via push_back()
被复制到A
的实例,这意味着您将丢失对象的派生部分。此问题称为object slicing。
如前所述,您可以通过将指针(或智能指针)存储到基类来避免这种情况,因此只有指针被复制到vector
:
std::vector<A*> things;
things.push_back(new B());
// ... use things:
things[0]->print();
// clean up later if you don't use smart pointers:
for(std::vector<A*>::iterator it = things.begin(); it != things.end(); ++it)
delete *it;
答案 2 :(得分:3)
您需要在基类中声明虚函数,在本例中为类a:
class A{
virtual void print(){cout << "A" << endl;}
}
即使你不在那些中写虚拟,其他类也会选择它(但你可以)。
Virtual告诉编译器可以覆盖该函数。当你不使用虚拟时,它就像你发现的那样被称为隐藏和工作方式不同。