C++内存布局

        今天闲来无事,研究起C++的内存布局来。得到几个结论,记录一下。

参考文献:http://haoel.blog.51cto.com/313033/124567(参考文献里面涉及的东西,这里都不再罗嗦。这里对文献做一点点补充。)

        先看看几个类的实现。

class Base
{
public :
	virtual void f()
	{
		cout<<"Base:f()"<<endl;
	}
};
class Child :public Base
{
public:
	virtual void f() 
	{
		cout<<"child:f()"<<endl;
	}
};

class B: public Child{
public :
	int data;
	virtual void f()
	{
		cout<<"B:f()"<<endl;
	}
	void h()
	{
		cout<<"B:h()"<<endl;
	}
};
        这里实现了3个类。一个基类Base,子类child,孙类B。这三个类都实现了虚函数f()。孙类有数据域data。为了方便使用,就public了。main函数实现如下:

void main(int argc, char* argv[])
{
	B b;
	B bb;
	b.data=100;
	cout<<*(((int*)&b)+1)<<endl;//间接访问数据域data
	
	cout<<*(int*)(&bb)<<endl;//获取B类的虚拟函数表
	cout<<*(int*)(&b)<<endl;//从另外一个对象中获取虚拟函数表的地址
	b.f();  b.h();
	b.B::f();//验证:每个类一个虚拟函数表
	b.Child::f();
	b.Base::f();
}
运行结果如下:

100
4649028
4649028
B:f()
B:h()
B:f()
child:f()
Base:f()
Press any key to continue

结论:

1.类的概念,只存在于编译时期。在代码运行时期,没有类,只有对象。

2.在单继承的情况,每个类有一个虚拟函数表,子类继承父类,只是拷贝父类的虚拟函数表,并不会修改父类的任何东西。最后几行的输出可证明。

3.一个具体的类只有一个虚拟函数表,它不属于任何对象。也就是说同一类的对象的虚拟跳转表的地址是一样的。第二行和第三行输出可以证明这个论点。

4.对于一个类,里面的虚拟函数,非虚拟函数,静态成员变量不占对象的空间。真正占用对象空间的只有数据域。也就是说,无论一个类有多少成员函数,这个类的对象的size不受影响。因为,成员函数只是存在于内存的代码段,而且所有相同类的对象共用相同的成员函数。

为了验证上面的结论,再举一个简单的好玩的例子。不用new,用结构体自己“new”一个对象出来。

定义一个类A:

class A 
{
	int a;
public:
	virtual void f()
	{
		cout<<"A:f()"<<endl;
	}
	void show()
	{
		cout<<"A:a="<<a<<endl;		
	}
};
很简单吧?

然后定义一个结构体:

typedef struct 
{
	int fun;
	int data;
} MyClass;
定义自己的“伪类”。fun表示虚拟跳转表,data是数据域。
void main(int argc, char* argv[])
{
	MyClass cl;
	cl.data=1000;//初始化数据

	//下面三行是为了初始化虚拟函数调整表
	A * a=new A();
	cl.fun=*(int*)(a);
	delete a;

	//“骗”计算机用A类的形式访问结构体cl。
	A* testA=(A*)&cl;

	//测试
	testA->f();
	testA->show();
}
运行结果:

A:f()
A:a=1000
Press any key to continue


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值