当前位置: 首页 > news >正文

析构和构造的顺序:成员对象、全局对象、局部对象

在 C++ 中,成员对象全局对象局部对象的生命周期和执行时机是内存管理的核心知识点,其规则由 C++ 标准严格定义,下面分模块详细拆解,结合示例说明关键细节。

一、成员对象的生命周期

成员对象是指作为类 / 结构体成员的对象(包括普通成员对象、静态成员对象),其生命周期完全依附于宿主对象(包含它的类对象),但静态成员对象是例外。

1. 非静态成员对象
  • 创建时机:宿主对象构造时,先构造所有非静态成员对象(按声明顺序,而非构造函数初始化列表顺序),再执行宿主类的构造函数体。
    • 如果是栈上的宿主对象:成员对象随宿主对象在栈帧创建时构造;
    • 如果是堆上的宿主对象(new创建):成员对象随宿主对象在堆上分配内存后构造;
    • 如果是全局 / 静态宿主对象:成员对象随宿主对象在程序启动阶段(main 前)构造。
  • 销毁时机:宿主对象析构时,先执行宿主类的析构函数体,再按成员对象声明的逆序析构所有非静态成员对象。
  • 核心规则:成员对象的生命周期与宿主对象完全一致,宿主对象销毁则成员对象必然销毁,反之亦然。

示例:非静态成员对象的生命周期

#include <iostream> using namespace std; class Member { public: Member() { cout << "Member 构造" << endl; } ~Member() { cout << "Member 析构" << endl; } }; class Host { private: Member m1; // 声明顺序:m1 先,m2 后 Member m2; public: Host() { cout << "Host 构造体执行" << endl; } ~Host() { cout << "Host 析构体执行" << endl; } }; int main() { cout << "创建栈上 Host 对象:" << endl; Host h; // 栈上宿主对象 cout << "main 结束,销毁 h" << endl; return 0; }

输出结果(体现构造 / 析构顺序):

创建栈上 Host 对象: Member 构造 // m1 先构造 Member 构造 // m2 后构造 Host 构造体执行 main 结束,销毁 h Host 析构体执行 Member 析构 // m2 先析构(逆序) Member 析构 // m1 后析构
2. 静态成员对象
  • 创建时机:属于类本身(而非某个对象),首次使用类之前构造(C++11 后保证线程安全),早于main函数执行,且仅构造一次(无论创建多少个宿主类对象)。
  • 销毁时机:程序退出阶段(main函数执行完毕后),按静态对象构造的逆序析构。
  • 核心规则:生命周期独立于宿主对象,与程序进程生命周期一致。

示例:静态成员对象的生命周期

class Host { public: static Member s_m; // 静态成员对象 Host() { cout << "Host 构造" << endl; } }; // 静态成员对象必须在类外初始化 Member Host::s_m; int main() { cout << "main 开始" << endl; Host h1, h2; // 创建两个宿主对象,静态成员对象仅构造一次 cout << "main 结束" << endl; return 0; }

输出结果

Member 构造 // 早于 main 执行 main 开始 Host 构造 Host 构造 main 结束 Host 析构 Host 析构 Member 析构 // main 结束后析构

二、全局 / 局部对象的执行时机

1. 全局对象(包括命名空间内的全局对象)
  • 构造时机:程序启动阶段(main函数执行之前),按对象在源码中的声明顺序构造(不同编译单元的全局对象构造顺序未定义)。
    • 注:如果全局对象被constexprinline修饰,可能在编译期初始化,但普通全局对象在运行期main前构造。
  • 析构时机:程序退出阶段(main函数执行完毕后),按构造的逆序析构。
  • 特性:存储在全局 / 静态存储区,生命周期贯穿整个程序运行期。
2. 局部对象(栈上局部对象)
  • 自动局部对象(无static修饰):

    • 构造时机:程序执行到对象的定义语句时构造;
    • 析构时机:程序执行到对象所在的作用域结束时(如}returngoto跳出作用域)析构;
    • 特性:存储在栈区,生命周期仅限于当前作用域。
  • 静态局部对象static修饰):

    • 构造时机:首次执行到对象定义语句时构造(C++11 后保证线程安全),仅构造一次;
    • 析构时机:程序退出阶段(main结束后),与全局对象一起析构(析构顺序为构造逆序);
    • 特性:存储在全局 / 静态存储区,生命周期贯穿程序运行期,但作用域仅限于局部。

示例:全局 / 局部对象的执行时机

// 全局对象 GlobalObj g_obj; void test() { // 自动局部对象 LocalObj auto_obj; // 静态局部对象 static LocalObj static_obj; cout << "test 函数执行中" << endl; } int main() { cout << "main 开始执行" << endl; test(); // 第一次执行 test,构造 auto_obj 和 static_obj test(); // 第二次执行 test,仅构造 auto_obj,static_obj 已存在 cout << "main 即将结束" << endl; return 0; }

输出结果

GlobalObj 构造 // main 前构造 main 开始执行 LocalObj 构造(auto) // 第一次 test,构造自动局部对象 LocalObj 构造(static) // 第一次 test,构造静态局部对象 test 函数执行中 LocalObj 析构(auto) // 第一次 test 结束,析构自动局部对象 LocalObj 构造(auto) // 第二次 test,重新构造自动局部对象 test 函数执行中 LocalObj 析构(auto) // 第二次 test 结束,析构自动局部对象 main 即将结束 main 执行完毕 GlobalObj 析构 // main 后析构全局对象 LocalObj 析构(static)// main 后析构静态局部对象

三、关键总结表

类型存储位置构造时机析构时机生命周期
非静态成员对象随宿主对象宿主构造时(声明顺序)宿主析构时(声明逆序)与宿主对象一致
静态成员对象全局 / 静态区main 前(首次用类前)main 后整个程序运行期
全局对象全局 / 静态区main 前(声明顺序)main 后(构造逆序)整个程序运行期
自动局部对象栈区执行到定义语句时作用域结束时仅当前作用域
静态局部对象全局 / 静态区首次执行到定义语句时main 后(构造逆序)整个程序运行期(局部作用域)
http://www.jsqmd.com/news/187878/

相关文章:

  • 制造业质检报告OCR:设备巡检记录自动上传至ERP系统
  • GitHub镜像同步工具推荐:保持HunyuanOCR代码库最新
  • 400 Bad Request错误日志分析:HunyuanOCR请求头缺失问题
  • C# Lambda默认参数使用全攻略:从语法到实际应用一步到位
  • 揭秘C#命名简化黑科技:using别名与元组联合使用的最佳实践
  • C#项目集成腾讯混元OCR?通过HTTP请求实现跨语言调用
  • 【实战】企业级物联网架构-元数据与物模型
  • 视频字幕识别新突破:腾讯混元OCR在动态场景下的应用实践
  • FMX学习之01安装
  • 为什么顶尖C#工程师都在用集合表达式?展开运算符的秘密全在这里
  • 降低部署成本利器:仅1B参数的腾讯混元OCR模型性能实测
  • 如何在欧拉OpenEuler系统中查找某个文件的位置
  • 公司内网怎么做隔离?VLAN 原理详解:网线里的“平行宇宙”
  • 内存安全战争爆发:C++的传统优势正在被Rust一点点蚕食?
  • 金融风控新工具:基于腾讯混元OCR的身份证与银行卡信息提取
  • C++网络通信兼容性难题突破,实现十年老系统平滑升级的关键路径
  • 欧拉系统(类似其他 Linux 发行版)通过Docker拉取的镜像存储路径及查询方法
  • 如何用GCC 14内置工具链实现零延迟调试?一线大厂都在用的方案
  • PyCharm激活码永久免费?警惕非法软件陷阱,专注合法AI工具如腾讯混元OCR
  • (Clang 17 RVO与NRVO优化深度剖析:性能提升的关键所在)
  • Faststone Capture功能复刻:基于Electron + HunyuanOCR
  • 火山引擎AI大模型定制化能力与HunyuanOCR通用性比较
  • C# 12顶级语句实战指南(复杂架构下的编码革命)
  • C# Lambda默认参数深度解析(90%开发者忽略的关键细节)
  • 400 Bad Request排查:Content-Type设置错误导致HunyuanOCR调用失败
  • PyCharm配置HunyuanOCR虚拟环境依赖项(requirements.txt)
  • HuggingFace镜像网站CDN加速效果实测:HunyuanOCR下载提速3倍
  • CSDN官网博主访谈:他们是如何用HunyuanOCR创业的?
  • 为什么你的C++微服务扛不住高并发?可能是负载均衡策略选错了!
  • 如何用C++打造自适应负载均衡引擎?这套设计方案必须收藏