为什么在C ++中添加虚拟关键字后此指针值发生了变化

时间:2017-12-25 08:51:04

标签: c++ this

考虑下面的代码行

javascript

在64位ubuntu机器上用g ++(4.8.4)编译后,结果是

#include<iostream>
using namespace std;

class base
{
int i;
public:
void printb()
{
cout << "This pointer of base   "<<this<<endl;
}
};

class derived: public base
{
int i;
public:
void printd()
{
cout << "This pointer of derived "<<this<<endl;
}
};

main()
{

derived d1;
d1.printd();
d1.printb();
}

根据我的理解,基本和派生的 这个 指针都是相同的,因为我们用单个对象调用。 我将虚拟关键字添加到派生类的printd()函数中,如下所示

This pointer of derived 0x7ffe74697ac0
This pointer of base    0x7ffe74697ac0

以上代码的输出如下

#include<iostream>
using namespace std;

class base
{
int i;
public:
void printb()
{
cout << "This pointer of base   "<<this<<endl;
}
};

class derived: public base
{
int i;
public:
virtual void printd()
{
cout << "This pointer of derived "<<this<<endl;
}
};

main()
{

derived d1;
d1.printd();
d1.printb();
}

这里 这个 指针值在derived和base中是不同的,即使用单个对象调用。每次运行程序时,派生之间存在1byte的差异 指针和基本 指针。 任何人都可以告诉为什么 指针的差异以及虚拟关键字如何影响 指针。

1 个答案:

答案 0 :(得分:4)

通过添加virtual关键字,您使derived多态。运行时多态性的常见实现是添加指向对象开头的指针。此 vptr 指向动态调度的函数表(通常称为 vtable )。

因此,base子对象(不是多态的)在隐藏指针的derived超级对象内部偏移。

您会看到指针自动调整,因为编译器会在调用成员函数时注入代码以执行此调整。这可确保printb能够在正确的位置访问base的所有(潜在)成员。