《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会先调用相应的析构函数再释放内存。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
1月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
5天前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
5天前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
1月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
5天前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
1月前
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
|
1月前
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
|
2月前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
87 19
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
89 13
|
4月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
173 5