C++ 类与对象进阶特性实战
掌握了基础封装后,很多开发者会在进阶特性上踩坑。为什么引用和 const 成员必须用初始化列表?static 成员如何管理共享状态?友元在什么场景下才安全?编译器又是如何优化拷贝构造的?
本文结合底层逻辑与代码示例,梳理这些特性的设计初衷与正确用法,避开工程开发中的高频陷阱。
一、再探构造函数:初始化列表的底层逻辑
习惯在函数体内赋值本质是'先默认初始化,再赋值'。初始化列表才是成员变量'定义初始化'的真正场所,直接决定初始状态。
1. 基础语法
以冒号开头,逗号分隔,每个成员后接初始值或表达式:
class Date {
public:
// 初始化列表:_year、_month、_day 在定义时直接初始化
Date(int year, int month, int day) : _year(year), _month(month), _day(day) {}
private:
int _year;
int _month;
int _day;
};
2. 必须使用初始化列表的场景
以下情况无法通过函数体内赋值初始化,否则编译报错:
(1)引用成员变量 引用必须在定义时绑定对象,函数体内赋值会被视为修改引用指向(C++ 不允许):
class A {
public:
// 正确:初始化列表绑定引用
A(int& ref) : _ref(ref) {}
private:
int& _ref;
};
(2)const 成员变量 const 变量必须在定义时初始化,函数体内赋值违反'常量不可修改'规则:
class A {
public:
A(int n) : _n(n) {}
private:
const int _n;
};
(3)无默认构造的自定义类型成员
若自定义类型没有默认构造(如 Time 只有带参构造),编译器无法自动初始化,必须在初始化列表显式传参:
class Time {
public:
( hour) : _hour(hour) {}
:
_hour;
};
{
:
( hour, year) : (hour), _year(year) {}
:
Time ;
_year;
};


