#include <iostream>
#include <stdio.h>
using std::endl;
using std::cout;
class Base
{
private:
int _ia;
public:
Base(int a)
:_ia(a)
{
cout<<"Base(int a)"<<endl;
}
virtual
void print()
{
cout<<"Base::_ia = "<<_ia<<endl;
}
};
class Derived
:public Base
{
private:
int _ib;
public:
Derived(int a,int b)
:Base(a)
,_ib(b)
{
cout<<"Derived(int a,int b)"<<endl;
}
void print()
{
cout<<"Derived::_ib = "<<_ib<<endl;
}
};
int main()
{
Derived derived(2,3);
cout<<"&derived = "<<&derived<<endl;
cout<<"derived对象地址(long*)&derived = "<<(long*)&derived<<endl; //内存布局中的第一个指针
cout<<"虚表地址*(long*)&derived = "<<(long*)*(long*)&derived<<endl;
derived.print();
cout<<"int ia = (int)*((long*)&derived+1) = "<<(int)*((long*)&derived+1)<<endl;
cout<<"int ib = (int)*((int*)&derived+3) = "<<(int)*((int*)&derived+3)<<endl;
cout<<sizeof(derived)<<endl;
printf("第一个虚函数入口地址 = %p\n",(long*)*(long*)*(long*)&derived);
typedef void (*pfunc)(void);
pfunc p=(pfunc)*(long*)*(long*)&derived;
p();
printf("第一个虚函数入口地址 = %p\n",p);
}
通过内存布局我们可以知道在普通继承时,派生类Derived继承Base时虚表位于前8个字节,然后是Base的数据成员其次是派生类的数据成员。通过这个特性我们可以通过指针访问对象中的任意一个数据成员和虚表中的函数。