每周技巧 #74:委托构造函数和继承构造函数
本节阅读量:本文翻译自 Abseil 官网的 Tip of the Week #74: Delegating and Inheriting Constructors。
原文最初作为 totw/74 发布于 2014 年 4 月 21 日。
“委托工作是有效的,前提是委托者自己也工作。”– Robert Half
当一个类有多个构造函数时,通常需要在每个变体中执行相似的初始化。为了避免代码重复,许多较旧的类会定义一个 private 的 SharedInit() 方法,并从构造函数中调用它。例如:
|
|
C++11 提供了一种新机制,也就是委托构造函数。它允许一个构造函数基于另一个构造函数来定义,从而更清晰地处理这类情况。如果类中有一些默认初始化代价昂贵的成员,这也能提升效率。
|
|
注意,如果你委托给另一个构造函数,就不能同时使用成员初始化列表;所有初始化都由被委托的构造函数完成。不过不要过度使用。如果共享代码所做的只是设置成员,那么分开的成员初始化列表或类内初始化器,可能比使用委托构造函数更清晰。请运用良好判断。
旁注:在委托构造函数返回之前,对象不被认为是完整的;实践中,这通常只在构造函数可能抛出异常时才重要,因为异常会让发起委托的对象处于不完整状态。
另一种较少见的构造函数代码重复,出现在通过 wrapper 扩展一个多构造函数类的行为时。例如,考虑 C 的一个“薄外衣”子类 D,它只是添加了一个新成员函数。
|
|
但 D 的构造函数怎么办?我们希望简单复用 C 的构造函数,而不是写出所有转发样板代码。C++11 通过新的继承构造函数机制允许这样做。
|
|
这种用于构造函数的新形式 “using”,与它过去用于成员函数的方式相匹配。
不过要注意,只有当派生类没有新增需要显式初始化的数据成员时,才真正应该继承构造函数。事实上,风格指南也警告不要继承构造函数,除非新成员(如果有)拥有类内初始化。
所以,当 C++11 的委托构造函数和继承构造函数能减少重复、消除转发样板代码,或以其他方式让你的类更简单、更清晰时,请放心使用它们。