C++中类成员对象采用has-a关系,构造时先调用成员构造函数再执行外层函数体,析构顺序相反;const和引用成员必须在初始化列表中初始化,且引用不能绑定临时对象;默认拷贝/赋值对成员递归调用对应操作。

可以,而且这是 C++ 中非常常见且推荐的组合(has-a)关系写法。只要被包含类有可访问的构造函数,编译器就能自动处理初始化和析构。
类对象作为成员时的构造/析构顺序
当一个类 Person 包含另一个类 Phone 的对象成员时,Phone 的构造函数总是在 Person 的构造函数体执行前调用;而析构顺序相反:Person 的析构函数体执行完后,才调用 Phone 的析构函数。
这个顺序是固定的,不受初始化列表中书写顺序影响——但初始化列表中成员的书写顺序必须与类定义中声明顺序一致,否则行为未定义。
- 若
Phone没有默认构造函数,Person必须在初始化列表中显式调用Phone的带参构造函数 - 若
Phone析构函数抛异常,而Person析构函数也正在执行,则程序直接终止(栈展开中断) - 成员对象的生命周期完全由其所在类的对象控制,不能手动 new/delete
引用类型或 const 类型能否作为类成员?
可以,但初始化规则更严格:
立即学习“C++免费学习笔记(深入)”;
-
const成员变量允许在声明时设缺省值(如const int x = 42;),但前提是该值在编译期可知;若为自定义类型,则要求其有默认构造函数 -
int&这类引用成员 禁止 在声明处设缺省值,必须在构造函数初始化列表中绑定到一个已存在的左值对象 - 例如:
Phone& p;声明合法,但Person()构造函数必须写成Person(Phone& ph) : p(ph) {},不能漏掉初始化列表 - 试图用临时对象初始化引用成员(如
: p(Phone()))会导致悬空引用,编译器通常会报错或警告
拷贝构造与赋值时,对象成员怎么处理?
默认情况下,编译器生成的拷贝构造函数和赋值运算符会对每个成员依次执行“对应操作”:
- 内置类型(
int、double等)做位拷贝(shallow copy) - 自定义类型成员(如
Phone p;)则调用其自身的拷贝构造函数或operator= - 如果
Phone内部持有裸指针并管理资源,而你没重载它的拷贝构造函数,那么Person的默认拷贝就会导致浅拷贝问题(两个Person对象共享同一块内存) - 此时必须显式为
Phone实现深拷贝逻辑,并确保Person不需要额外干预——编译器会自动调用它
真正容易被忽略的是:成员对象的访问权限和生命周期完全独立于外层类的 public/protected/private 设置;但如果你把成员声明为 private,外部就无法直接访问,哪怕它是另一个完整类的对象。


















