昨天看了下耗子叔的c++虚函数表的实现,想起看《Inside_the_C++_Object_Model 》里指针修正的过程,做了下试验,发现将子类地址赋值给基类指针的过程中确实会将基类指针进行修正,谷歌上搜了搜没发现有中文博客涉及这个内容,就在这里做个记录吧。
首先,先看懂这两篇关于虚函数表实现的文章
C++ 虚函数表解析
C++ 对象的内存布局
然后是《Inside_the_C++_Object_Model》3.4章关于继承时成员与虚函数表在内存中的分布情况
上代码
#include<iostream>
class A{
public:
virtual void A_f(){}
};
class B{
public:
virtual void B_f(){}
};
class C:public A,public B{
public:
void A_f(){}
};
int main()
{
A *a;
B *b;
C *c=new C();
a=c,b=c;
std::cout<<" a is "<<a<<" b is "<<b<<" c is "<<c<<std::endl;
}
ubuntu上的试验结果
a is 0x1f5b010 b is 0x1f5b018 c is 0x1f5b010
看完了前面提到的资料其实蛮好理解的,实例C的虚函数表有两个表项,第一个指向基类A和C的虚函数,第二个指向基类B的虚函数,所以在指针赋值的时候,a和c都指向相同的虚函数表表项,而对b进行修正,指到了第二个表项(正好内存地址高1个字)。