C++ 为什么在C+;中添加虚拟关键字后此指针值会发生更改+;

C++ 为什么在C+;中添加虚拟关键字后此指针值会发生更改+;,c++,this,C++,This,考虑下面的代码行 #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

考虑下面的代码行

#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();
}
根据我的理解,base和derived这个指针将是相同的,因为我们使用单个对象调用。 我在派生类的printd()函数中添加了virtual关键字,如下所示

#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();
}
This pointer of derived 0x7ffee969b1d0
This pointer of base    0x7ffee969b1d8
此处指针值在派生和基中是不同的,即使使用单个对象调用也是如此。每次我运行程序时,派生指针和基指针之间的差值为1字节。
有人能告诉我为什么这个
指针存在这种差异,以及虚拟关键字是如何影响这个
指针的。

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

因此,非多态的
base
子对象通过隐藏指针在
派生的
超级对象内偏移


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

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

因此,非多态的
base
子对象通过隐藏指针在
派生的
超级对象内偏移


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

不是1个字节,而是8个字节。一个指针在你的平台上相当于一个字节。因为你强迫编译器建立一个虚拟函数表。它不是1个字节,而是8个字节。指针在您的平台上的字节数。因为您强制编译器设置虚拟函数表。
This pointer of derived 0x7ffee969b1d0
This pointer of base    0x7ffee969b1d8