《Imperfect C++中文版》——2.1 对象生命周期

简介:

本节书摘来自异步社区出版社《Imperfect C++中文版》一书中的第2章,第2.1节,作者: 【美】Matthew Wilson,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.1 对象生命周期

Imperfect C++中文版
每个C++对象的生命周期都分为4段:不存在、部分构造、实例化、部分析构[Stro1997]。此外,一个对象所占用的空间必须在该对象构造之前就分配好,并且在该对象析构之后被释放。1

对象可以以下例4种标准方式诞生。

全局对象,包括真正的“全局”对象、位于名字空间中的对象,以及作为类静态成员的对象,生存于任何函数的作用域之外。它们通常在main()函数被执行之前就已经构造完毕,并且在main()结束之后被自动销毁(见11.1节)。它们所占用的空间是由编译器/连接器分配的。
栈对象生存在局部执行框架上,位于函数中。它们在声明点上被创建(其声明点也是定义点),并在超出作用域时被自动销毁。它们所占用的内存空间是通过调整栈指针而分配的,由编译器/连接器所决定。
堆对象生存于堆/自由存储区上[Stro1997]。它们使用new操作符进行创建,并且通过显式调用delete操作符而销毁。它们所占用的空间来自自由存储区,而自由存储区可能会出现空间不够用的情况,从而导致新建对象失败(参见32.2节,以便了解关于这种情况的后果以及如何处理的详细讨论)。C++语言基础设施确保内存分配以及对构造函数的调用会连在一起进行,2并且确保对析构函数的调用以及内存释放也会连在一起进行。3
作为另一个对象的一部分。在这种情况下,该子对象的生命期依赖于外围对象的生命期(见第5章)。
就地构造
除了标准途径外,你还可以通过placement new(定位new)和显式析构来明确地控制对象所占的内存和生命期:

byte_t    *p = . . . // 满足SomeClass的对齐要求的内存块
SomeClass &sc = *new(p) SomeClass(); // 创建实例
. . .
sc.SomeMethod();
. . .
sc.~SomeClass(); // 显式地销毁实例,p指向的内存块依然存在

毫无疑问,这不是好的编码习惯。姑且不管容器的实现(容器是按值而不是按引用存储的),很少有合理的理由来使用该技术。

1从概念上说是这样。不过前一个对象所占用的内存在该对象析构之后可以被再次使用,其间没有任何实质上的内存释放,例如这在STL容器中就比较常见。
2译者注:即调用new操作符的时候,不但分配内存,还会调用相应的构造函数。
3译者注:即delete会先调用相应的析构函数再释放内存。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
15天前
|
存储 编译器 C语言
C++入门: 类和对象笔记总结(上)
C++入门: 类和对象笔记总结(上)
30 0
|
18天前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
60 0
|
15天前
|
编译器 C语言 C++
【c++】类和对象(三)构造函数和析构函数
朋友们大家好,本篇文章我们带来类和对象重要的部分,构造函数和析构函数
|
15天前
|
存储 编译器 C语言
【c++】类和对象(二)this指针
朋友们大家好,本节内容来到类和对象第二篇,本篇文章会带领大家了解this指针
【c++】类和对象(二)this指针
|
15天前
|
存储 编译器 C语言
【c++】类和对象(一)
朋友们,大家好,本篇内容我们来对类和对象进行初步的认识
|
16天前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
108 1
|
16天前
|
监控 安全 算法
悬垂引用与临时对象在C++中的深入探讨: 风险、原因与预防策略
悬垂引用与临时对象在C++中的深入探讨: 风险、原因与预防策略
54 3
|
17天前
|
存储 编译器 对象存储
C++第十弹---类与对象(七)
C++第十弹---类与对象(七)
|
18天前
|
设计模式 算法 测试技术
【C/C++ 编程 哑对象】了解和学习哑对象在C/C++ 编程中的使用
【C/C++ 编程 哑对象】了解和学习哑对象在C/C++ 编程中的使用
42 2
|
18天前
|
Java 编译器 C语言
C++:类与对象(3)
C++:类与对象(3)