C ++继承,重写时仍会调用基函数

时间:2010-03-06 00:43:51

标签: c++ abstraction inheritance

我有以下两个类,一个继承自另一个

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 ++中使用它并且它一直没有为我工作

3 个答案:

答案 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告诉编译器可以覆盖该函数。当你不使用虚拟时,它就像你发现的那样被称为隐藏和工作方式不同。