C ++ - 在父母列表中调用子方法覆盖

时间:2017-11-11 17:36:41

标签: c++ inheritance linked-list

以下是我正在谈论的示例程序:

#include <iostream>
#include <list>

using namespace std;

class Thing {
    public:
        virtual void jump() { cout << "Called from Thing class" << endl; }
};

class Car: public Thing {
    public:
        virtual void jump() { cout << "Vroom vroom; imma car biotch" << endl; }
};

int main(int argc, char* argv[]) {

    Car myCar;

    list<Thing> myList;

    myList.push_back(myCar);

    std::list<Thing>::iterator iterator;
    for (iterator = myList.begin(); iterator != myList.end(); ++iterator) {
        iterator->jump();
    }

    return 0;
}

输出:

Called from Thing class

我想要做的是列出&#34; Things&#34;。我希望能够从Thing类添加子类的实例;那么我希望能够从迭代器中调用它们的覆盖函数。

唯一的问题是,即使在使用&#34;虚拟&#34;关键字,迭代器使用Thing :: jump函数而不是Car :: jump函数。

我能做些什么才能使它不仅可以与Car一起使用,还可以使用Thing,Car等所有潜在的子类来覆盖&#34;跳跃&#34;功能

1 个答案:

答案 0 :(得分:0)

在C ++中,他们所说的是价值观。您有一个Thing列表,而不是Thing或派生类型的列表。

当您在列表中插入内容时,会创建一份副本。在插入派生类型实例的情况下,这将复制对象的Thing部分,称为对象切片(std::unique_ptr<Base>部分被切掉)。

有多种方法可以存储多态数据,但基类型的实例不是其中之一。

例如,您可以将#include <iostream> #include <list> #include <memory> class Thing { public: virtual void jump() { std::cout << "Called from Thing class\n"; } ~Thing(){} }; class Car: public Thing { public: virtual void jump() { std::cout << "Vroom vroom; I am a car\n"; } }; 存储在列表中。如果这样做,请确保您的基类型具有虚拟析构函数,以避免在默认删除器删除时未定义的行为。

std::list<std::unique_ptr<Thing>> myList;

myList.push_back(std::make_unique<Car>());

for(auto&& ptr:myList){
    ptr->jump();
}

然后在主要:

{{1}}