我有以下代码
#include <iostream>
#include <vector>
class Entity {
public:
virtual void func() = 0;
};
class Monster : public Entity {
public:
void func();
};
void Monster::func() {
std::cout << "I AM A MONSTER" << std::endl;
}
class Buddha : public Entity {
public:
void func();
};
void Buddha::func() {
std::cout << "OHMM" << std::endl;
}
int main() {
const int num = 5; // How many of each to make
std::vector<Entity*> t;
for(int i = 0; i < num; i++) {
Monster m;
Entity * e;
e = &m;
t.push_back(e);
}
for(int i = 0; i < num; i++) {
Buddha b;
Entity * e;
e = &b;
t.push_back(e);
}
for(int i = 0; i < t.size(); i++) {
t[i]->func();
}
return 0;
}
但是,当我运行它时,不是每个类都打印出自己的消息,而是打印出“佛”消息。我希望每个对象都能打印出自己的信息:怪物打印出怪物信息,佛像打印佛信息。
我做错了什么?
答案 0 :(得分:13)
您需要使用'new'从堆中分配对象。这里发生的是你正在创建临时对象,将指针指向这些对象,然后这些对象被破坏。是的,这与许多其他语言不同。 :)
相反,请尝试:
int main() {
const int num = 5; // How many of each to make
std::vector<Entity*> t;
for(int i = 0; i < num; i++) {
Monster* m = new Monster;
t.push_back(m);
}
for(int i = 0; i < num; i++) {
Buddha* b = new Buddha;
t.push_back(b);
}
for(int i = 0; i < t.size(); i++) {
t[i]->func();
}
// This is very important!
for(int i = 0; i < t.size(); i++) {
delete t[i];
}
return 0;
}
当你看到这样奇怪的行为时,请检查实际矢量的内容。你会发现你所有的老虎机都有相同的价值,这就是堆叠上持有临时怪物然后是临时大佛的位置。
答案 1 :(得分:2)
这是因为您的m
和b
对象是各自循环的本地对象。每次迭代后,它们都会超出范围,从而使向量包含悬空指针。在这种情况下,行为是未定义的。你的程序很可能已经崩溃了。
P.S。 Virtual inheritance完全不同。
答案 2 :(得分:1)
你在这里有未定义的行为 - 你不能在具有更大范围的向量中存储指向局部变量的指针,因为变量将在你调用它们上面的虚函数时消失。您需要使用new
动态分配存储指针的对象,并在完成后记得用delete
释放它们。