C++类的成员变量是在堆区还是在栈区
C++内存分配基础
- 在理解C++类的成员变量存储位置之前,我们先要了解C++中的几种主要内存区域
- 栈区(Stack): 栈区内存由编译器自动分配和释放,存储函数的局部变量,参数等。栈区内存具有生命周期短,分配效率高的特点
- 堆区(Heap): 堆区内存由程序员手动分配和释放(使用new和delete)。堆区内存的生命周期由程序员控制,适合存储需要长时间存在的数据
- 静态存储区(Static Storage): 该区域存储静态数据成员和全局变量,内存分配在程序开始时进行,直到程序结束时才释放
- 代码区和常量区: 存储程序代码和常量数据
类的成员变量存储位置
- 类的成员变量的存储位置取决于类的实例(对象)如何创建。主要有以下几种情况
栈上分配的对象
- 当一个对象在栈上分配时,成员变量也存储在栈上
堆上分配的对象
- 当使用new关键字动态分配一个对象时,对象和其成员变量会存储在堆上。
静态存储区的对象
- 如果一个对象是全局变量或静态变量,那么它会被分配在静态存储区。
- 这些对象的内存在程序开始时分配,并且在程序运行期间一直存在,直到程序结束时才会释放。因此,静态对象和全局对象的成员变量存储在静态存储区中。
C __BEGIN_DECLS 是什么
__BEGIN_DECLS
和 __END_DECLS
是在C语言和C++代码混合时使用的宏。它们用于确保 C 头文件在被 C++ 编译器编译时能够正确处理 C 函数原型。
当在 C++ 环境中包含 C 头文件时,需要用 extern "C"
来告诉 C++ 编译器这些声明是 C 语言的,以便正确处理名字修饰(name mangling)。__BEGIN_DECLS
和 __END_DECLS
宏正是为了简化这一过程而设计的。
1 |
这段代码的含义是:
- 如果编译器是 C++ 编译器 (
__cplusplus
被定义),则__BEGIN_DECLS
被定义为extern "C" {
,__END_DECLS
被定义为}
。 - 如果编译器是 C 编译器,则这两个宏都定义为空。
使用这些宏可以这样写一个头文件:
1 |
|
当这个头文件在 C++ 代码中被包含时,my_function
的声明会被包含在 extern "C"
块中,从而避免了 C++ 名字修饰问题。在 C 代码中,宏会被定义为空,所以对代码没有影响。