目录
一.类域
二.计算类的大小
类存储方式一:
类中包含各个成员(包括函数在内)。
类存储方式二:
类的存储方式三:
练习题:
三.C++结构内存对齐规则
一.类域
其实类也是个域,拥有一对花括号,它与我们之前学习的命名空间域有相似之处,但也大有不同。命名空间域是一堵墙,需要权限才能去打开,但只要有了权限,里面的一切就都能访问到;而类域也可以认为是一堵墙,但它是一堵虚拟墙,需要实例化对象后才能访问其中一部分内容(会有访问限定修饰符),如下图代码所示:
//命名空间域
namespace bit {
int x = 100;
double y = 15.93;
int Add(int j, int i) {
return i + j;
}
}
int main() {
bit::x = 99;
bit::y = 3.14;
int a = 1, b = 2;
bit::Add(a, b);
cout << "x:"<<bit::x << endl;
cout << "x:" << bit::y << endl;
cout << "Add:" << bit::Add(a,b) << endl;
return 0;
}
![](https://img-blog.csdnimg.cn/732a522e13304b3ca2a84d190c8bd75c.png)
而类域代码:
//类域
class ListNode {
public:
void ListInit(int capa) {
}
void ListPush(int x) {
}
private:
int* _a;
int _top;
int _capacity;
};
int main(){
ListNode lst1;
lst1.ListInit(4);
lst1.ListPush(1);
lst1.ListPush(2);
}
对于类必须创建实例化对象,否则,不允许访问任何成员:
![](https://img-blog.csdnimg.cn/7c1f2e701df54701997417ad74aaecef.png)
二.计算类的大小
如下图代码所示:一个类中既包含了函数,又包含了成员变量,该如何计算类的存储大小呢?
class A
{
public:
void PrintA()
{
cout << _a << endl;
}
private:
char _a;
};
int main() {
cout << sizeof(A) << endl;
A aa;
cout << sizeof(aa) << endl;
return 0;
}
答案为什么都是1呢?这就要提到类存储的三种方式了。
类存储方式一:
类中包含各个成员(包括函数在内)。
![](https://img-blog.csdnimg.cn/4d81a87ea48f4d37a0620f5002d5aab4.png)
这种每个对象中成员变量是不同的,成员函数也不同。
类存储方式二:
![](https://img-blog.csdnimg.cn/6c066578f3a744c4a20e5cc9b2934447.png)
表明类中只存储类成员变量,对于成员函数则是使用一个地址去指向它们。
当使用类A实例化两个对象时,让两个对象都调用PrintA();会发现它们调用的是同一个函数,连地址都相同。
![](https://img-blog.csdnimg.cn/3c09d27ea2594100a61a9c31e0881210.png)
类的存储方式三:
只保存成员变量,成员函数存放在公共的代码段。
这三种方式是官方一步步改进出来的,最终将方式三保留了下来, 对于第一种方式来说,当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。 对于第二种方式,举个栗子来讲:好比盖小区,小区内造了5栋楼,100套房子,每一套房子的主人不同,厕所厨房都是独立的,而那些锻炼器材,例如健身房,游泳池又不能每家都有,所以开辟了一个公共区域(成员函数),但是每个房子的主人会获得一把去这里的钥匙(给地址),让每家的人都可以去;对于第三种方式来说,是把成员函数放在一个公共区域,一看就可以找到,不需要给每家人钥匙,是没有锁的,很方便。
所以编译器就是使用的第三种存储方式,这也印证了前面例题中为什么类和类对象的大小都是1了,只有char_a被存储进去了。
练习题:
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
int main() {
cout << sizeof(A2) << endl;
cout << sizeof(A3) << endl;
return 0;
}
系统为什么给A2,A3各分配一个字节?
只是用来占位,不存储有效数据,只是标识对象存在!
三.C++结构内存对齐规则
因为C++兼容C语言,所以它的内存对齐与C完全一样。
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。