以下是我正在谈论的示例程序:
#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;功能
答案 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}}