[英]Vector of pointers to base class, odd behaviour calling virtual functions
我有以下代码
#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;
}
但是,当我运行它时,它们都打印出“佛”消息,而不是每个类打印出自己的消息。 我希望每个对象都能打印出自己的信息:怪物打印出怪物信息,佛像打印佛信息。
我做错了什么?
您需要使用“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;
}
当你看到这样奇怪的行为时,请检查实际向量的内容。 你会发现你所有的老虎机都有相同的价值,这就是堆叠上持有临时怪物然后是临时大佛的位置。
发生这种情况是因为m
和b
对象是各自循环的本地对象。 每次迭代后,它们都会超出范围,从而使向量包含悬空指针。 在这种情况下,行为是未定义的。 你的程序很可能已经崩溃了。
PS 虚拟继承是完全不同的东西。
你在这里有未定义的行为 - 你不能在具有更大范围的向量中存储指向局部变量的指针,因为当你调用它们上面的虚函数时,变量就会消失。 您将需要使用new
动态分配要存储指针的对象,并在完成后记得使用delete
它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.