我正在尝试创建任何可迭代的方法来存储子类对象。
我目前正在使用指向超类的指针向量,但这似乎不允许使用任何特定于子类的声明。
class piece
{
public:
int foo()
{
return 1;
}
};
class pawn : public piece
{
public:
int foo()
{
return 2;
}
};
std::vector<piece*> pieces;
pieces.push_back(new pawn());
pieces[0]->foo(); // returns 1 though pieces[0] should be a pawn
当我希望它返回2时,对pieces [0]-> foo()的调用将返回1。
调试显示“ new pawn()”创建了一个分段指针,因此我了解了为什么它不使用pawn函数,但是我不知道为什么它首先不是pawn。 / p>
答案 0 :(得分:2)
这是因为您的foo
方法不是virtual
。在其他几种面向对象的语言中,默认情况下,所有方法都是“虚拟”的,但它们不在C ++中。 “虚拟”表示要在运行时确定要调用的函数。当您使用非虚拟方法时,编译器会在编译时根据静态类型信息决定要调用的函数。
在这种情况下,由于您拥有piece
的向量,因此编译器总是确定应调用pieces[0]->piece::foo()
,而不会检查子类中是否有更完善的版本。如果您有一个虚拟方法,则编译器确定应调查该对象,以根据其类型确定要调用的对象。您将在foo
和piece
中更改pawn
的声明:
virtual int foo()
中的{li> piece
; virtual int foo() override
。请参阅“ Why do we need virtual functions in C++?”。用肯尼思·沃登(Kenneth Worden)的话说,“虚拟允许子类方法被调用,即使该对象被视为其超类也是如此。”