含有虚函数的内存布局

http://hi.baidu.com/hj11yc/item/0428b1ba2c7e8aadeaba93b3

另外:

可参考:

http://blog.csdn.net/haoel/article/details/3081385

我们来看看有虚函数,并且是有虚基类的类的内存布局

我们看看一个有成员的例子:

#include<iostream>
using namespace std;
class A{
public:
	int a;
	A():a(1){}
	virtual void show(void){cout<<"call A"<<endl;}
};
class B:virtual public A{
public:
	int b;
	B():b(2){}
	virtual void show(void){cout<<"call B"<<endl;}
};
class C:virtual public A{
public:
	int c;
	C():c(3){}
	virtual void show(void){cout<<"call C"<<endl;}
};
class D:public B,public C{
public:
	int d;
	D():d(4){}
	virtual void show(void){cout<<"call D"<<endl;}
};
int main(void)
{
	D d;
	cout<<"the address begin:"<<&d<<endl;
	cout<<""<<endl;
	cout<<hex<<*(((int *)&d)+0)<<endl;
	cout<<hex<<*(((int *)&d)+1)<<endl;
	cout<<hex<<*(((int *)&d)+2)<<endl;
	cout<<hex<<*(((int *)&d)+3)<<endl;
	cout<<hex<<*(((int *)&d)+4)<<endl;
	cout<<hex<<*(((int *)&d)+5)<<endl;
	cout<<hex<<*(((int *)&d)+6)<<endl;
	cout<<hex<<*(((int *)&d)+7)<<endl;
	cout<<hex<<*(((int *)&d)+8)<<endl;
	cout<<hex<<*(((int *)&d)+9)<<endl;
	system("pause");
	return 1;
}


输出来看看呢?

‍‍

可以看个大概是怎么分布的,但是哪些是vptr,社么是vbptr呢》》?????

来看个详细的例子

#include<iostream>
using namespace std;
class A{
public:
 int a;
 A():a(1){}
 virtual void show(void){cout<<"call A"<<endl;}
};
class B:virtual public A{
public:
 int b;
 B():b(2){}
 virtual void show(void){cout<<"call B"<<endl;}
};
class C:virtual public A{
public:
 int c;
 C():c(3){}
 virtual void show(void){cout<<"call C"<<endl;}
};
class D:public B,public C{
public:
 int d;
 D():d(4){}
 virtual void show(void){cout<<"call D"<<endl;}
};
typedef void (*FUN )(void);
int main(void)
{
 D d;
 cout<<"the address begin:"<<&d<<endl;
 cout<<""<<endl;
    cout<<hex<<*(((int *)&d)+0)<< "   ";cout<<dec<<*((int *)(*((int *)&d+0))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+0))+1)<<endl;
 cout<<hex<<*(((int *)&d)+1)<<endl;
 cout<<hex<<*(((int *)&d)+2)<<"   ";cout<<dec<<*((int *)(*((int *)&d+2))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+2))+1)<<endl;//这两个都是指向virtual base table的指针,第一项都为0,第二项是偏移量
 cout<<hex<<*(((int *)&d)+3)<<endl;
 cout<<hex<<*(((int *)&d)+4)<<endl;
 cout<<hex<<*(((int *)&d)+5)<<endl;
 cout<<hex<<*(((int *)&d)+6)<<"   ";cout<<dec<<*((int *)(*((int *)&d+6))+0)<<"   ";
 cout<<hex<<*(((int *)&d)+7)<<endl;
 cout<<hex<<*(((int *)&d)+8)<<endl;
 cout<<hex<<*(((int *)&d)+9)<<endl;
 cout<<"//"<<endl;
      /*FUN fun11=(FUN)*((int *)(*((int *)&d+0))+0);
  fun11();
        fun11=(FUN)*((int *)(*((int *)&d+2))+0);
  fun11();*这两个不能运行,说明没有指向函数,则说明类中的第一个,第三个数据是指向基类的指针。并且在上面的输出中可以看到这两个指针的第一项都为0,说明没有虚函数,这个没有虚函数说的是没有自己独特于基类的虚函数。所以第一项为0,第二项为偏移量。
  FUN fun11=(FUN)*((int *)(*((int *)&d+6))+0);
  fun11();
  /*fun11=(FUN)*((int *)(*((int *)&d+6))+1);
  fun11();*///这个也不能,因为只有一个虚函数,并且是三个共用的,所以上面一个能运行,这个不能
 system("pause");
 return 1;
}

看看结果:

‍‍  

可以看到什么问题么??看看我嗦分析的。也许你看到注释分析的过后会问,B,C的vptr呢?因为他们没有自己的虚函数,所以没有产生,只有vbptr,是偏移量。所以都指向了基类的vptr处。

如果不相信,你可以为B单独添加一个虚函数,然后你就知道了。不信来看看:

#include<iostream>
using namespace std;
class A{
public:
	int a;
	A():a(1){}
	virtual void show(void){cout<<"call A"<<endl;}
};
class B:virtual public A{
public:
	int b;
	B():b(2){}
	virtual void show(void){cout<<"call B"<<endl;}
	virtual void go(void){cout<<"call B:;go"<<endl;}
};
class C:virtual public A{
public:
	int c;
	C():c(3){}
	virtual void show(void){cout<<"call C"<<endl;}
};
class D:public B,public C{
public:
	int d;
	D():d(4){}
	virtual void show(void){cout<<"call D"<<endl;}
};
typedef void (*FUN )(void);
int main(void)
{
	D d;
	cout<<"the address begin:"<<&d<<endl;
	cout<<""<<endl;
	cout<<hex<<*(((int *)&d)+0)<< endl;
	cout<<hex<<*(((int *)&d)+1)<<"   ";cout<<dec<<*((int *)(*((int *)&d+1))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+1))+1)<<endl;
	cout<<hex<<*(((int *)&d)+2)<<endl;
	cout<<hex<<*(((int *)&d)+3)<<endl;
	cout<<hex<<*(((int *)&d)+4)<<endl;
	cout<<hex<<*(((int *)&d)+5)<<endl;
	cout<<hex<<*(((int *)&d)+6)<<endl;
	cout<<hex<<*(((int *)&d)+7)<<endl;
	cout<<hex<<*(((int *)&d)+8)<<endl;
	cout<<hex<<*(((int *)&d)+9)<<endl;
	cout<<"//"<<endl;
	FUN fun11=(FUN)*((int *)(*((int *)&d+0))+0);
	fun11();
	system("pause");
	return 1;
}


我只为B增加了一个自己的虚函数,看看输出呢?


再解释下-4的含义,意思就是说有自己的虚函数,如果没有的话,这个值是0;24是偏移量,记住,基类偏移量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值