簡體   English   中英

指向基類的指針,調用虛函數的奇怪行為

[英]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;
}

當你看到這樣奇怪的行為時,請檢查實際向量的內容。 你會發現你所有的老虎機都有相同的價值,這就是堆疊上持有臨時怪物然后是臨時大佛的位置。

發生這種情況是因為mb對象是各自循環的本地對象。 每次迭代后,它們都會超出范圍,從而使向量包含懸空指針。 在這種情況下,行為是未定義的。 你的程序很可能已經崩潰了。

PS 虛擬繼承是完全不同的東西。

你在這里有未定義的行為 - 你不能在具有更大范圍的向量中存儲指向局部變量的指針,因為當你調用它們上面的虛函數時,變量就會消失。 您將需要使用new動態分配要存儲指針的對象,並在完成后記得使用delete它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM