一、传统构造函数的痛点
在C++11之前,当多个构造函数需要执行相同的初始化逻辑时,开发者往往面临两难选择:
cpp
class DataProcessor {
std::string dataPath;
bool verbose;
int bufferSize;
public:
// 基础版本
DataProcessor(const std::string& path)
: dataPath(path), verbose(false), bufferSize(1024) {
validatePath();
}
// 带详细设置的版本
DataProcessor(const std::string& path, bool verb, int bufSize)
: dataPath(path), verbose(verb), bufferSize(bufSize) {
validatePath(); // 重复初始化代码
checkBufferSize();
}
};
存在的三大问题:
- 初始化代码重复
- 修改时需要多处同步
- 可维护性降低
二、委托构造函数的核心语法
2.1 基本形式
cpp
class ClassName {
public:
ClassName(参数列表1) : ClassName(委托参数) { /*附加逻辑*/ }
ClassName(参数列表2) { /*主构造函数*/ }
};
2.2 实际应用示例
cpp
class NetworkConnection {
std::string address;
int port;
int timeout;
bool encrypted;
void initSecurity() { /* 通用初始化 */ }
public:
// 主构造函数
NetworkConnection(const std::string& addr, int p, int t, bool enc)
: address(addr), port(p), timeout(t), encrypted(enc) {
initSecurity();
}
// 委托构造:默认超时
NetworkConnection(const std::string& addr, int p)
: NetworkConnection(addr, p, 5000, false) {}
// 委托构造:默认端口
NetworkConnection(const std::string& addr)
: NetworkConnection(addr, 8080) {}
};
三、执行流程解析
cpp
class Demo {
int a, b, c;
public:
Demo(int x) : Demo(x, x*2) { // 步骤1:委托给两参数构造
c = x * 3; // 步骤3:执行附加逻辑
}
Demo(int x, int y) : a(x), b(y) { // 步骤2:执行主构造
validateValues();
}
};
执行顺序:
- 委托构造函数的初始化列表
- 目标构造函数的初始化列表
- 目标构造函数的函数体
- 委托构造函数的函数体
四、典型应用场景
4.1 默认参数构造
cpp
class FileHandler {
std::filesystem::path filePath;
std::ios::openmode mode;
public:
FileHandler(const std::string& path, std::ios::openmode m)
: filePath(path), mode(m) { verifyAccess(); }
FileHandler(const std::string& path)
: FileHandler(path, std::ios::in | std::ios::binary) {}
};
4.2 参数验证中心化
cpp
class TemperatureSensor {
double minTemp, maxTemp;
void validateRange() {
if (minTemp >= maxTemp) throw std::invalid_argument("...");
}
public:
TemperatureSensor(double min, double max)
: minTemp(min), maxTemp(max) { validateRange(); }
TemperatureSensor(double singleTemp)
: TemperatureSensor(singleTemp-5, singleTemp+5) {}
};
4.3 工厂模式支持
cpp
class Product {
protected:
Product(int baseParam) { /* 基础初始化 */ }
public:
static Product createA() { return Product(1); }
static Product createB() { return Product(2); }
};