具有虚拟函数的类型转换 [英] typecasting with virtual functions

查看:97
本文介绍了具有虚拟函数的类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,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;但是当我向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;
}

为什么pA不等于pC?他们是否仍然指向内存中相同的C对象?

解决方案

你的指针,因为新的虚函数导致一个vtable指针注入你的对象。 VC ++将vtable指针放在对象的开头(这是典型的,但纯粹是一个内部细节)。



让我们向A添加一个新字段

  class A {
public:
int a;
};
//其他类不变

现在, pA A 看起来像这样:

  pA  - > | a | 0x0000004 

一旦你将B和C添加到组合中,你会得到:

  pC  - > | vtable | 0x0000000 
pA - > | a | 0x0000004
| i | 0x0000008
| c | 0x000000C

如您所见, pA 指向vtable之后的数据,因为它不知道vtable的任何内容或如何使用它,甚至不知道它在那里。 pC 知道vtable,所以它直接指向表,这简化了它的使用。


In the code below, 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;
}

But when I add a pure virtual function to B and implement it in 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;
}

Why is pA not equal to pC in this case? Don't they both still point to the same "C" object in memory?

解决方案

You're seeing a different value for your pointer because the new virtual function is causing the injection of a vtable pointer into your object. VC++ is putting the vtable pointer at the beginning of the object (which is typical, but purely an internal detail).

Let's add a new field to A so that it's easier to explain.

class A {
public:
    int a;
};
// other classes unchanged

Now, in memory, your pA and A look something like this:

pA --> | a      |          0x0000004

Once you add B and C into the mix, you end up with this:

pC --> | vtable |          0x0000000
pA --> | a      |          0x0000004
       | i      |          0x0000008
       | c      |          0x000000C

As you can see, pA is pointing to the data after the vtable, because it doesn't know anything about the vtable or how to use it, or even that it's there. pC does know about the vtable, so it points directly to the table, which simplifies its use.

这篇关于具有虚拟函数的类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆