2.2对象结构的发展和演化(笔记)

(1)非静态的成员变量(普通成员变量)跟着类对象走(存在对象内部),也就是每个类对象都有自己的成员变量;

下面这个类占8字节

class A
{
public:
	int a;
	int b;
};

(2)静态成员变量跟对象没有什么关系,所以肯定不会保存在对象内部,是保存在对象外面(表示所占用的内存空间和类对象无关)的。

再加入一个静态成员之后,类还是8个字节,说明静态成员不会储存在对象内部.

class A
{
public:
	int a;
	int b;
	static int sa;
};
int A::sa = 12;

(3)成员函数:不管静态的还是非静态,全部都保存在类对象之外。所以不管几个成员函数,不管是否是静态的成员函数,对象的sizeof的大小都是不增加的;

加入一个普通成员函数和一个静态成员函数之后 该类还是占8个字节

class A
{
public:
	int a;
	int b;
	static int sa;
public:
	void func() {};
	static int func1() 
	{
		return sa;
	};
};

(4)虚函数:不管几个虚函数,sizeof()都是多了4个字节(32位是多4字节)。

这个类占了12字节

class A
{
public:
	int a;
	int b;
	static int sa;
public:
	void func() {};
	static int func1() 
	{
		return sa;
	};
	virtual void vTest()
	{
		cout << "test" << endl;
	}
};
int A::sa = 12;
  • 类里只要有一个虚函数(或者说至少有一个虚函数),这个类 会产生一个 指向 虚函数 的指针。有两个虚函数,那么这个类 就会产生两个指向虚函数的指针。
  • 类本身  指向虚函数的 指针(一个或者一堆)要有地方存放,存放在一个表格里,这个表格我们就称为“虚函数表(virtual table【vtbl】)”;
  • 这个虚函数表一般是保存在可执行文件中的,在程序执行的时候载入到内存中来。
  • 虚函数表是基于类的,跟着类走的;
  • 说说类对象,这四个字节的增加,其实是因为虚函数的存在;因为有了虚函数的存在,导致系统往类对象中添加了一个指针,
  • 这个指针正好指向这个虚函数表,很多资料上把这个指针叫vptr;这个vptr的值由系统在适当的时机(比如构造函数中通过增加额外的代码来给值);

(5)字节对齐

class A
{
public:
	int a;
	int b;
	char c;
	static int sa;
public:
	void func() {};
	static int func1() 
	{
		return sa;
	};
	//virtual void vTest()
	//{
	//	cout << "test" << endl;
	//}
};
int A::sa = 12;

       char本身占一个字节,但加入一个char类型的变量之后,该类的大小变成了12字节,增加了4字节 ,这是因为编译器为了提高访问速度,进行了内存对齐,32位是默认按照4字节对齐的.

在类定义上面加上#pragma pack(1)

#pragma pack(1)
class A
{
public:
	int a;
	int b;
	char c;
	static int sa;
public:
	void func() {};
	static int func1() 
	{
		return sa;
	};
	//virtual void vTest()
	//{
	//	cout << "test" << endl;
	//}
};
int A::sa = 12;

结果是该类占了9个字节,#pragma pack(1) 意识是按1字节对齐 .

总结:

  1. 静态数据成员不计算在类对象sizeof()内;
  2. 普通成员函数和静态成员函数不计算在类对象的sizeof()内
  3. 虚函数不计算在类对象的sizeof()内,但是虚函数会让类对象的sizeof()增加4个字节以容纳虚函数表指针。
  4. 虚函数表[vtbl]是基于类的(跟着类走的,跟对象没关系,不是基于对象的);
  5. 如果有多个数据成员,那么为了提高访问速度,某些编译器可能会将数据成员之间的内存占用比例进行调整。(内存字节对齐)
  6. 不管什么类型指针char *p,int *q;,该指针占用的内存大小是固定的

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值