繁体   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