如何在C ++中的向量中存储多个子类的对象

时间:2019-01-22 21:11:09

标签: c++

我正在尝试创建任何可迭代的方法来存储子类对象。

我目前正在使用指向超类的指针向量,但这似乎不允许使用任何特定于子类的声明。

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>

1 个答案:

答案 0 :(得分:2)

这是因为您的foo方法不是virtual。在其他几种面向对象的语言中,默认情况下,所有方法都是“虚拟”的,但它们不在C ++中。 “虚拟”表示要在运行时确定要调用的函数。当您使用非虚拟方法时,编译器会在编译时根据静态类型信息决定要调用的函数。

在这种情况下,由于您拥有piece的向量,因此编译器总是确定应调用pieces[0]->piece::foo(),而不会检查子类中是否有更完善的版本。如果您有一个虚拟方法,则编译器确定应调查该对象,以根据其类型确定要调用的对象。您将在foopiece中更改pawn的声明:

  • virtual int foo()中的{li> piece;
  • {{1}中的virtual int foo() override

请参阅“ Why do we need virtual functions in C++?”。用肯尼思·沃登(Kenneth Worden)的话说,“虚拟允许子类方法被调用,即使该对象被视为其超类也是如此。”