「C++系列」一篇文章说透【存储类】
文章目录
- 一、C++ 存储类
- 1. 类的定义
- 2. 对象的创建
- 3. 对象在内存中的布局
- 4. 对象的存储位置
- 二、auto 存储类
- 1. `auto`的基本用法
- 2. `auto`与存储类的关系
- 1) 自动存储类(最常见的)
- 2) 静态存储类
- 3) 动态存储类(通过new)
- 三、register 存储类
- 1. register 存储类的特点
- 2. 案例
- 3. 注意事项
- 四、static 存储类
- 1. 局部静态变量
- 2. 全局静态变量
- 3. 静态类成员变量
- 4. 静态类成员函数
- 五、extern 存储类
- 1. 声明全局变量
- 2. 声明函数
- 3. extern "C"
- 4. 注意事项
- 六、mutable 存储类
- 1. 基本用法
- 2. 示例
- 3. 注意事项
- 七、thread_local 存储类
- 1. 基本用法
- 2. 注意事项
- 八、相关链接
一、C++ 存储类
在C++中,类的存储方式主要涉及到类的定义、对象的创建以及这些对象在内存中的布局。C++是一种静态类型、编译型语言,支持面向对象的编程范式。下面详细解释这些概念:
1. 类的定义
类是C++中用户定义的类型(UDT),用于封装数据(称为成员变量或属性)和函数(称为成员函数或方法)。类的定义不会为对象分配任何内存,它只是描述了对象的结构。
class MyClass { public: int x; void func() { // 成员函数实现 } };
2. 对象的创建
当你使用类来创建对象时,才会在内存中为对象分配空间。这个空间用于存储对象的成员变量。成员函数则不直接存储在对象中,而是存储在程序的代码段中,对象通过其成员函数指针(通常是通过隐式的this指针)来访问这些函数。
MyClass obj; // 创建一个MyClass类型的对象obj
3. 对象在内存中的布局
- 成员变量:对象的成员变量(包括从基类继承的成员变量)按照它们在类中声明的顺序,在内存中连续存储。成员变量的对齐和填充(padding)可能会根据编译器和平台的不同而有所不同,以优化内存访问速度。
- 成员函数:成员函数不直接存储在对象中,而是存储在程序的代码段(Code Segment)中。当对象调用成员函数时,该函数通过隐式的this指针来访问对象的成员变量。
- 静态成员:静态成员变量在程序的全局数据段中分配一次内存,所有对象共享同一份静态成员变量的拷贝。静态成员函数则不直接访问任何对象的成员变量(除非通过对象或类名显式传递),因此它们没有this指针。
4. 对象的存储位置
对象的存储位置取决于其生命周期和作用域:
- 自动存储期:在函数或代码块内声明的局部变量(包括对象)存储在栈(Stack)上,其生命周期仅限于定义它们的代码块。
- 静态存储期:全局对象、静态局部变量以及静态成员变量存储在全局数据段(Global Data Segment)或静态数据段(Static Data Segment)中,它们在程序的整个执行期间都存在。
- 动态存储期:通过new操作符动态分配的对象存储在堆(Heap)上,其生命周期由new和delete操作符控制。
二、auto 存储类
在C++中,auto 关键字不是用来直接声明存储类的,而是用来自动推导变量类型的。存储类(也称为存储期或生命周期)指的是变量在内存中保留的时间长度,常见的存储类有自动(automatic)、静态(static)、寄存器(register,但现代C++中很少使用,且其优化行为通常由编译器自动处理)、外部(extern)以及动态分配(通过new操作符)。
然而,当我们在C++中使用auto关键字时,我们是在告诉编译器自动根据初始化表达式的类型来推导变量的类型。这并不意味着auto变量就有特定的存储类;它的存储类取决于其声明的上下文。
1. auto的基本用法
下面是一个使用auto的简单案例,它演示了如何自动推导变量的类型,但并没有直接涉及到存储类的概念:
#include #include int main() { // 自动推导为int类型 auto a = 10; std::cout 1, 2, 3, 4, 5}; auto b = v; // 注意:这里b是v的一个拷贝,而不是引用 std::cout auto x = 10; // x具有自动存储类,因为它是在函数内部声明的局部变量 // ... } // x的作用域结束,x的生命周期也结束 // 可以在这里访问y } register int counter = 0; // 建议编译器将counter存储在寄存器中 for (int i = 0; i
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。