C++对象构造与析构顺序解析

来源:3D模型作者:乐少头衔:工程师
导读:本期聚焦于小伙伴创作的《C++对象构造与析构顺序解析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++对象构造与析构顺序解析》有用,将其分享出去将是对创作者最好的鼓励。

C++中对象的构造和析构顺序遵循明确的规则,不同场景下的顺序存在差异,理解这些规则是正确管理对象资源的基础。

C++对象构造与析构顺序解析

基础单个对象的构造与析构顺序

对于没有继承、没有成员对象的单个普通类对象,构造和析构的顺序是最基础的场景。构造时先执行构造函数体内的逻辑,析构时先执行析构函数体内的逻辑,整体顺序相反。

我们可以通过以下代码观察单个对象的构造析构过程:

#include <iostream>
using namespace std;

class BaseObj {
public:
    BaseObj() {
        cout << "BaseObj 构造函数执行" << endl;
    }
    ~BaseObj() {
        cout << "BaseObj 析构函数执行" << endl;
    }
};

int main() {
    BaseObj obj;
    return 0;
}

运行上述代码,输出结果为:

BaseObj 构造函数执行
BaseObj 析构函数执行

组合对象的构造与析构顺序

当一个类包含其他类的对象作为成员时,就形成了组合关系。组合对象的构造顺序是先构造所有成员对象,再执行当前类的构造函数体;析构顺序则完全相反,先执行当前类的析构函数体,再析构所有成员对象,且成员对象的析构顺序和声明顺序相反。

示例代码如下:

#include <iostream>
using namespace std;

class MemberA {
public:
    MemberA() {
        cout << "MemberA 构造函数执行" << endl;
    }
    ~MemberA() {
        cout << "MemberA 析构函数执行" << endl;
    }
};

class MemberB {
public:
    MemberB() {
        cout << "MemberB 构造函数执行" << endl;
    }
    ~MemberB() {
        cout << "MemberB 析构函数执行" << endl;
    }
};

class ComboObj {
private:
    // 成员声明顺序为MemberB在前,MemberA在后
    MemberB b;
    MemberA a;
public:
    ComboObj() {
        cout << "ComboObj 构造函数执行" << endl;
    }
    ~ComboObj() {
        cout << "ComboObj 析构函数执行" << endl;
    }
};

int main() {
    ComboObj obj;
    return 0;
}

运行输出结果为:

MemberB 构造函数执行
MemberA 构造函数执行
ComboObj 构造函数执行
ComboObj 析构函数执行
MemberA 析构函数执行
MemberB 析构函数执行

可以看到成员对象的构造顺序和声明顺序一致,析构顺序和声明顺序相反,和初始化列表中的顺序无关。

继承关系下的对象构造与析构顺序

存在继承关系时,构造顺序为先构造基类对象,再构造派生类对象;析构顺序相反,先析构派生类对象,再析构基类对象。如果有多层继承,则按照继承层级从最顶层基类到最底层派生类依次构造,析构时反向进行。

以下是单继承的示例代码:

#include <iostream>
using namespace std;

class Parent {
public:
    Parent() {
        cout << "Parent 构造函数执行" << endl;
    }
    ~Parent() {
        cout << "Parent 析构函数执行" << endl;
    }
};

class Child : public Parent {
public:
    Child() {
        cout << "Child 构造函数执行" << endl;
    }
    ~Child() {
        cout << "Child 析构函数执行" << endl;
    }
};

int main() {
    Child obj;
    return 0;
}

运行输出结果为:

Parent 构造函数执行
Child 构造函数执行
Child 析构函数执行
Parent 析构函数执行

不同作用域对象的构造与析构顺序

对象的作用域也会影响构造和析构的时机,常见的作用域包括全局、静态局部、普通局部:

  • 全局对象:在程序启动前构造,程序结束时析构
  • 静态局部对象:第一次执行到定义语句时构造,程序结束时析构
  • 普通局部对象:进入作用域时构造,离开作用域时析构

示例代码验证不同作用域的顺序:

#include <iostream>
using namespace std;

class GlobalObj {
public:
    GlobalObj() {
        cout << "全局对象 构造" << endl;
    }
    ~GlobalObj() {
        cout << "全局对象 析构" << endl;
    }
};

GlobalObj g_obj; // 全局对象

void testFunc() {
    static StaticLocalObj s_obj; // 静态局部对象
    LocalObj l_obj; // 普通局部对象
}

class StaticLocalObj {
public:
    StaticLocalObj() {
        cout << "静态局部对象 构造" << endl;
    }
    ~StaticLocalObj() {
        cout << "静态局部对象 析构" << endl;
    }
};

class LocalObj {
public:
    LocalObj() {
        cout << "普通局部对象 构造" << endl;
    }
    ~LocalObj() {
        cout << "普通局部对象 析构" << endl;
    }
};

int main() {
    cout << "进入main函数" << endl;
    testFunc();
    cout << "离开main函数前" << endl;
    return 0;
}

运行输出结果为:

全局对象 构造
进入main函数
静态局部对象 构造
普通局部对象 构造
普通局部对象 析构
离开main函数前
静态局部对象 析构
全局对象 析构

数组对象的构造与析构顺序

对象数组的构造顺序是按照下标从0到n-1依次构造,析构顺序则相反,从n-1到0依次析构。

示例代码如下:

#include <iostream>
using namespace std;

class ArrayObj {
public:
    ArrayObj(int id) {
        this->id = id;
        cout << "ArrayObj " << id << " 构造" << endl;
    }
    ~ArrayObj() {
        cout << "ArrayObj " << id << " 析构" << endl;
    }
private:
    int id;
};

int main() {
    ArrayObj arr[3] = {ArrayObj(1), ArrayObj(2), ArrayObj(3)};
    return 0;
}

运行输出结果为:

ArrayObj 1 构造
ArrayObj 2 构造
ArrayObj 3 构造
ArrayObj 3 析构
ArrayObj 2 析构
ArrayObj 1 析构

常见注意事项

  • 不要在构造函数的初始化列表中改变成员对象的构造顺序,构造顺序只和成员声明的顺序有关
  • 析构函数不要抛出异常,否则可能导致后续对象析构失败,引发未定义行为
  • 如果基类没有虚析构函数,通过基类指针删除派生类对象时,派生类的析构函数不会执行,可能导致资源泄漏
  • 全局对象和静态对象的构造顺序在不同编译单元之间没有明确的顺序保证,不要依赖跨编译单元的全局对象构造顺序

C++对象构造对象析构构造顺序析构顺序修改时间:2026-07-19 15:06:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。