好吧所以我一直在研究游戏引擎,我遇到了一个问题...目前我有一个类的层次结构(图像 - >动画 - >对象)所有这些都有一个方法get_type(),我有这个问题:
如果我使用new关键字声明派生类,或静态地,我得到所需的结果:
object instance;
cout << instance.get_type(); //returns an int value
object* pointer = new(object);
cout << pointer->get_type();
Run Code Online (Sandbox Code Playgroud)
从上面的代码中,控制台输出3.该方法在对象中声明为:
图像类:
class image{
public:
virtual int get_type();
};
int object::get_type(){
return 1;
}
Run Code Online (Sandbox Code Playgroud)
动画类:
class animation: public image{
public:
virtual int get_type();
};
int animation::get_type(){
return 2;
}
Run Code Online (Sandbox Code Playgroud)
对象类:
class object: public animation{
public:
virtual int get_type();
};
int object::get_type(){
return 3;
}
Run Code Online (Sandbox Code Playgroud)
现在当我做这样的事情时出现了问题:
object* t = &object();
cout << t->get_type();
Run Code Online (Sandbox Code Playgroud)
结果现在是1.
如果我从对象类的类声明中删除virtual关键字,它可以正常工作(代码的最后一位返回3)
问题:如何在不使用new关键字的情况下从对象*指针中利用我的虚方法?原因是,我正在填充一个带有指向这些对象的向量并在我添加它们时创建它们,所以我希望能够执行以下操作:
vector<object*> objects; //not imgs or animations
for (int a = 0; a < 20; a++){
objects.push_back(&object());
}
Run Code Online (Sandbox Code Playgroud)
并有任何对象[x] - > get_type(); 返回正确的类类型.原因是我在我的游戏中使用的事件系统需要原始类型...
TLDR; 我真的很遗憾,你能帮忙吗?
这是因为构造函数和析构函数都在代码中运行:
object* t = &object();
cout << t->get_type();
Run Code Online (Sandbox Code Playgroud)
在&object()创建(匿名的,临时的)目标,立即自毁它(因为它是暂时的),然后分配现在已经遭到破坏对象的地址t.(如果你将警告级别提高到足够高,你的编译器可能会警告你这个表达式.)
尝试创建一个在您使用它时粘附的对象:
object my_object();
object *t = &my_object;
cout << t->get_type();
Run Code Online (Sandbox Code Playgroud)
当您使用非虚函数时,t在编译时使用指针的类型来确定要调用的方法.当您使用虚函数时,在虚拟分派期间在运行时使用对象内的信息来决定调用哪个函数.由于您的对象在调用时未正确构造(因为它已被破坏),结果严格未定义但最终调用了错误的函数.