在标准C++中,建构式不能调用其它的建构式;每个建构式必须自己初始化所有的成员或是调用一个共用的成员函数。基类的建构式不能够直接作为派生类的建构式;就算基类的建构式已经足够,每个衍伸的类型仍必须实做自己的建构式。类型中non-constant的数据成员不能够在声明的地方被初始化,它们只能在建构式中被初始化。 C++11将会提供这些问题的解决方案。
C++11允许建构式调用其他建构式,这种做法称作委托或转接(delegation)。 仅仅只需要加入少量的代码,就能让数个建构式之间达成功能复用(reuse)。Java以及C#都有提供这种功能。C++11 语法如下:
class SomeType { int number; string name; SomeType( int i, string& s ) : number(i), name(s){} public: SomeType( ) : SomeType( 0, "invalid" ){} SomeType( int i ) : SomeType( i, "guest" ){} SomeType( string& s ) : SomeType( 1, s ){ PostInit(); } };
C++03中,建构式运行退出代表对象建构完成; 而允许使用转接建构式的 C++11 则是以"任何"一个建构式退出代表建构完成。 使用转接的建构式,函数本体中的代码将于被转接的建构式完成后继续运行(如上例的 PostInit())。 若基底类型使用了转接建构式,则派生类的建构式会在"所有"基底类型的建构式都完成后, 才会开始运行。
C++11 允许派生类手动继承基底类型的建构式, 编译器可以使用基底类型的建构式完成派生类的建构。 而将基类的建构式带入派生类的动作, 无法选择性地部分带入, 要不就是继承基类全部的建构式,要不就是一个都不继承(不手动带入)。 此外,若牵涉到多重继承,从多个基底类型继承而来的建构式不可以有相同的函数签名(signature)。 而派生类的新加入的建构式也不可以和继承而来的基底建构式有相同的函数签名,因为这相当于重复声明。
语法如下:
class BaseClass { public: BaseClass(int iValue); }; class DerivedClass : public BaseClass { public: using BaseClass::BaseClass; };
此语法等同于 DerivedClass 声明一个DerivedClass(int) 的建构式。 同时也因为 DerivedClass 有了一个继承而来的建构式,所以不会有默认建构式。
另一方面,C++11可以使用以下的语法完成成员初始化:
class SomeClass { public: SomeClass() {} explicit SomeClass(int iNewValue) : iValue(iNewValue) {} private: int iValue = 5; };
若是建构式中没有设置iValue的初始值,则会采用类定义中的成员初始化,令iValue初值为5。在上例中,无参数版本的建构式,iValue便采用默认所定义的值; 而带有一个整数参数的建构式则会以指定的值完成初始化。
成员初始化除了上例中的赋值形式(使用"=")外,也可以采用建构式以及统一形的初始化(uniform initialization,使用"{}")。