使用虚函数进行类型转换

use*_*280 7 c++ virtual casting

在下面的代码中,pC == pA:

class A
{
};

class B : public A
{
public:
    int i;
};

class C : public B
{
public:
    char c;
};

int main()
{
    C* pC = new C;
    A* pA = (A*)pC;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是当我向B添加一个纯虚函数并在C中实现它时,pA!= pC:

class A
{
};

class B : public A
{
public:
    int i;
    virtual void Func() = 0;
};

class C : public B
{
public:
    char c;
    void Func() {}
};

int main()
{
    C* pC = new C;
    A* pA = (A*)pC;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,为什么pA不等于pC?难道他们两个仍然指向内存中相同的"C"对象?

Der*_*ark 6

您看到指针的值不同,因为新的虚函数导致将vtable指针注入对象.VC++将vtable指针放在对象的开头(这是典型的,但纯粹是内部细节).

让我们为A添加一个新字段,以便更容易解释.

class A {
public:
    int a;
};
// other classes unchanged
Run Code Online (Sandbox Code Playgroud)

现在,在内存中,你pAA这个样子:

pA --> | a      |          0x0000004
Run Code Online (Sandbox Code Playgroud)

将B和C添加到混合中后,您最终会得到:

pC --> | vtable |          0x0000000
pA --> | a      |          0x0000004
       | i      |          0x0000008
       | c      |          0x000000C
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,pA指向vtable 之后的数据,因为它不了解vtable或如何使用它,甚至它就在那里. pC确实了解vtable,因此它直接指向表格,这简化了它的使用.