可重用构造函数是指在C++中能够被其他构造函数调用的构造函数,主要用于避免代码重复和提高代码可维护性。C++11引入了委托构造函数(Delegating Constructor)的概念,允许一个构造函数调用同一个类中的另一个构造函数。
class MyClass {
private:
int a;
double b;
std::string c;
void init(int x, double y, const std::string& z) {
a = x;
b = y;
c = z;
}
public:
MyClass() {
init(0, 0.0, "");
}
MyClass(int x) {
init(x, 0.0, "");
}
MyClass(int x, double y) {
init(x, y, "");
}
MyClass(int x, double y, const std::string& z) {
init(x, y, z);
}
};
class MyClass {
private:
int a;
double b;
std::string c;
public:
// 目标构造函数
MyClass(int x, double y, const std::string& z) : a(x), b(y), c(z) {}
// 委托构造函数
MyClass() : MyClass(0, 0.0, "") {}
MyClass(int x) : MyClass(x, 0.0, "") {}
MyClass(int x, double y) : MyClass(x, y, "") {}
};
现象:构造函数A委托给B,B又委托给A,形成无限循环
原因:构造函数之间形成了循环调用链
解决方案:确保委托链最终会到达一个非委托构造函数
// 错误示例 - 循环委托
class Circle {
Circle() : Circle(1.0) {} // 委托给下面的构造函数
Circle(double r) : Circle() {} // 又委托回去
};
// 正确示例
class Circle {
Circle() : Circle(1.0) {} // 委托给下面的构造函数
Circle(double r) : radius(r) {} // 非委托构造函数
private:
double radius;
};
现象:编译错误,提示"mem-initializer for 'member' follows constructor delegation"
原因:在委托构造函数中同时尝试初始化成员变量
解决方案:所有成员初始化必须在被委托的构造函数中完成
// 错误示例
class Example {
Example() : Example(0), member(42) {} // 错误:不能同时委托和初始化成员
Example(int x) {}
int member;
};
// 正确示例
class Example {
Example() : Example(0) {} // 只委托
Example(int x) : member(x == 0 ? 42 : x) {} // 在被委托的构造函数中初始化
int member;
};
现象:在多继承情况下,虚基类可能被多次初始化
原因:委托构造函数可能绕过虚基类的正确初始化路径
解决方案:确保虚基类在最派生的构造函数中初始化
class VirtualBase {
public:
VirtualBase(int x) { /*...*/ }
};
class Derived : virtual public VirtualBase {
public:
// 正确:最派生的构造函数初始化虚基类
Derived(int x) : VirtualBase(x) {}
// 委托给上面的构造函数
Derived() : Derived(0) {}
};
通过合理使用可重用构造函数,可以显著提高C++类的设计质量和代码可维护性。
没有搜到相关的文章