📌 C++小课堂:当类的成员是另一个类的对象时,构造和析构顺序是怎样的?

大家好!今天我们来聊聊 C++ 中一个非常实用但容易被忽略的细节:当一个类的成员变量本身是一个类的对象时,它的构造和析构是如何进行的?

这种情况在面向对象编程中非常常见。比如,一个人(Person)拥有一部手机(Phone),那么 Person 类中就可以包含一个 Phone 类型的成员变量。这种“类中包含类对象”的设计,我们称之为 对象成员(Object Member)


🔧 关键知识点

✅ 构造顺序

先调用成员对象的构造函数,再执行当前类的构造函数体

✅ 析构顺序

与构造相反——先执行当前类的析构函数体,再调用成员对象的析构函数

💡 注意:成员对象的初始化必须通过初始化列表完成,不能在构造函数体内赋值(尤其是没有默认构造函数时)!


🖥️ 示例代码(支持中文输出)

下面这段代码完整演示了上述过程,并使用 #include <windows.h> 配合 SetConsoleOutputCP(CP_UTF8) 实现控制台中文正常显示:

#include<windows.h>
#include<iostream>
usingnamespacestd;

class Phone
{
public:
    Phone(string name)
    {
        m_PhoneName = name;
        cout << "Phone构造" << endl;
    }

    ~Phone()
    {
        cout << "Phone析构" << endl;
    }

    string m_PhoneName;

};


class Person
{
public:

    //初始化列表可以告诉编译器调用哪一个构造函数
    Person(string name, string pName) :m_Name(name), m_Phone(pName)
    {
        cout << "Person构造" << endl;
    }

    ~Person()
    {
        cout << "Person析构" << endl;
    }

    void playGame()
    {
        cout << m_Name << " 使用" << m_Phone.m_PhoneName << " 牌手机! " << endl;
    }

    string m_Name;
    Phone m_Phone;

};
void test01()
{
    //当类中成员是其他类对象时,我们称该成员为 对象成员
    //构造的顺序是 :先调用对象成员的构造,再调用本类构造
    //析构顺序与构造相反
    Person p("To be number.wan" , "Xiaomi");
    p.playGame();

}


int main() {
    SetConsoleOutputCP(CP_UTF8);
    test01();
    return0;
}

🖨️ 运行结果

图片

从输出可以看出:

  • Phone 先构造(因为它是 Person 的成员)

  • Person 后构造

  • 程序结束时,Person 先析构,Phone 后析构

这完全符合 C++ 标准规定的生命周期管理规则!


✅ 小结
  • 对象成员必须通过初始化列表进行初始化(尤其当成员类没有默认构造函数时)。

  • 构造顺序由成员声明顺序决定,与初始化列表中的书写顺序无关!

  • 析构总是按构造的逆序进行,确保资源安全释放。

掌握这一点,能帮助你写出更健壮、更符合 C++ 语义的类设计!


📘 如果你觉得这篇内容对你有帮助,欢迎点赞、转发,也欢迎在评论区留下你的疑问或想法!下期我们继续深入 C++ 面向对象的其他核心机制!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐