我是C ++的新手,Pls帮助我解决这个问题,即使class1,class2和class3没有使用像基类和派生类关系这样的继承,编译器如何进行动态绑定 - > class derived :: public class base {};
#include <iostream>
using namespace std;
class Class1{
public:
virtual void f(){
cout << "f() in class 1\n";
}
void g(){
cout << "g() in class 1\n";
}
};
class Class2{
public:
virtual void f(){
cout << "f() in class 2\n";
}
void g(){
cout << "g() in class 2\n";
}
};
class Class3{
public:
virtual void f(){
cout << "f() in class 3\n";
}
};
int main()
{
Class1 object1, *p;
Class2 object2;
Class3 object3;
p = &object1;
p->f();
p->g();
p = (Class1 *)&object2;
p->f();
p->g();
p = (Class1 *) &object3;
p->g();
return 0;
}
Output:
f() in class 1
g() in class 1
f() in class 2
g() in class 1
g() in class 1
答案 0 :(得分:4)
未定义的行为。
在完全不相关的类型之间进行转换并访问其内容是未定义的行为,因此任何事情都可能发生,包括看起来像是有效的。
不要这样做。
此外,在该上下文中使用C风格的演员类似于reinterpret_cast
。你应该尽可能避免使用它。例如,如果使用static_cast
,则会出现编译错误。
答案 1 :(得分:-1)
这是对此处发生的事情的解释: 1.)如果类中至少存在一个虚函数,则为该类创建vtable,并为构造函数创建调用对象的vptr。此vtable仅包含虚拟功能。然后,编译器在运行时(动态绑定)期间从指针引用的对象类型而不是指针本身的类型解析每个多态调用。 所以在这里: 2.)1级将有一个vtable,让我们调用vtable(1级)。然后vtable(2级)和vtable(3级)。将有4个vptrs,vptr(对象1),vptr(p),vptr(对象2)和vptr(对象3)。 3.)所以,当电话; p =(1级*)&amp;对象2;对 - &GT; F();并且在运行时解析p-&gt; g(),编译器将查找由p引用的对象的对象vptr,即对象2;虽然它是铸造但仍然被引用的对象是对象2因此将调用vptr(对象2),它将在vtable(类2)中搜索虚函数f并调用它。在搜索g()时,vptr不会在vtable中找到它,因此会找到类1的指针本身,并调用class 1&#39; s g。 4.)注意:虚函数与多态而非继承有关。