考虑下面的代码行
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的差异此 指针和基本 此 指针。 任何人都可以告诉为什么 此 指针的差异以及虚拟关键字如何影响 此 指针。
答案 0 :(得分:4)
通过添加virtual
关键字,您使derived
多态。运行时多态性的常见实现是添加指向对象开头的指针。此 vptr 指向动态调度的函数表(通常称为 vtable )。
因此,base
子对象(不是多态的)在隐藏指针的derived
超级对象内部偏移。
您会看到指针自动调整,因为编译器会在调用成员函数时注入代码以执行此调整。这可确保printb
能够在正确的位置访问base
的所有(潜在)成员。