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