[英]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.