在C++11标准之前,如果需要编写多个具有不同参数的构造函数,必须在每个构造函数中重复初始化代码,因为无法在类的构造函数内部调用其他构造函数。
无法在其他构造函数中使用已经存在的初始化逻辑导致代码重复和在更改初始化逻辑时的错误:更新一个构造函数时,容易忘记其他构造函数。
随着C++11的推出,出现了“委托构造函数”的机制,使得一个类的构造函数可以通过初始化列表的语法调用该类的另一个构造函数。
代码示例:
class Widget { public: Widget() : Widget(0, "default") {} Widget(int n) : Widget(n, "user") {} Widget(int n, std::string name) : size(n), label(name) {} private: int size; std::string label; };
现在,所有的公共逻辑集中在一个“主”构造函数中,其他构造函数委托调用。
关键特性:
可以通过在构造函数体内调用函数来委托调用给另一个构造函数吗?
不可以。构造函数之间仅能通过初始化列表调用,而不能在构造函数体内部调用。如果在构造函数体内调用函数,成员对象将已经被初始化。
如果创建构造函数之间的“委托环”会发生什么?
循环委托(例如,A委托B,而B又委托A)会导致C++编译错误:构造函数之间不能有无限递归。
可以通过派生类的委托构造函数委托给基类构造函数吗?
不可以。委托构造函数只能在一个类内部工作。要调用基类构造函数,需要使用单独的语法:
class Base { public: Base(int) {} }; class Derived : public Base { public: Derived() : Base(42) {} };
三个构造函数,每个都显式初始化字段,逻辑不同步 — 仅更改一个构造函数,其他两个将不正确。
优点:
缺点:
一个主构造函数,其他构造函数委托于它,所有初始化逻辑集中。
优点:
缺点: