本周小贴士#74:委托和继承构造函数

Posted -飞鹤-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本周小贴士#74:委托和继承构造函数相关的知识,希望对你有一定的参考价值。

作为totw/74最初始发表于2014年4月21日

由radley White (bww@google.com)创作

“委托的工作有效,前提是委托工作的人也是如此。”——罗伯特.哈夫

当一个类有多个构造函数时,通常需要对每个变量执行类似的初始化操作。为了避免代码重复,许多旧的类求助于定义一个私有的SharedInit()方法,供构造函数调用。例如:

class C {
 public:
  C(int x, string s) { SharedInit(x, s); }
  explicit C(int x) { SharedInit(x, ""); }
  explicit C(string s) { SharedInit(0, s); }
  C() { SharedInit(0, ""); }
 private:
  void SharedInit(int x, string s) {}
};

C++11提供了一种新的机制,委托构造函数,允许根据另一个构造函数来定义一个构造函数,以此来更清晰地解决此类问题。如果一个类有默认初始化代价高的成员时,这也是一种有效的收益。

class C {
 public:
  C(int x, string s) {}
  explicit C(int x) : C(x, "") {}
  explicit C(string s) : C(0, s) {}
  C() : C(0, "") {}
};

请注意,如果你委托另一个构造函数,那么你不能使用成员初始化列表——所有的初始化必须通过委托的构造函数来完成。不要做得太过了。如果所有的共享代码都是设置成员,那么单独的成员初始化列表或类内初始化可能比使用委托构造函数更清晰。做出好的决断。

旁白:在委托构造函数返回前,一个对象不被认为是完整的;实际上,当它们让来自委托的对象处于不完整的状态时,如果构造函数能够扔出,这才是唯一关键的。

当通过包装器来扩展多构造函数的类的行为时,会出现另外一种不太常见的构造函数代码形式。例如,考虑一个只添加新成员函数的C的“veneer”子类。

class D : public C {
 public:
  void NewMethod();
};

但是关于D的构造函数是什么呢?我们想简单地复用C中的代码,而不是写出所有转发的样板,而C++11通过新的继承构造函数机制来允许这样做。

class D : public C {
 public:
  using C::C;  // 继承所有来自C的构造函数
  void NewMethod();
};

这种用于构造函数的新形式"using"与之前对成员函数的使用相匹配。

注意,无论如何,只有当派生类不用添加需要显式初始化的数据成员时,构造函数才应该被继承。实际上,风格指南反对继承构造函数,除非新的成员(如果有)具有类内初始化。

因此,请继续使用C++11的委托和继承构造函数,当它们减少重复、消除转发样板或者其他的让你的类变得更简单和清晰时。

以上是关于本周小贴士#74:委托和继承构造函数的主要内容,如果未能解决你的问题,请参考以下文章

本周小贴士#120:返回值是不可触碰的

本周小贴士#143:C++11 删除的函数(= delete)

本周小贴士#101:返回值,引用和生命周期

本周小贴士#143:C++11 删除的函数(= delete)

本周小贴士#61:默认的成员初始化器

本周小贴士#109:在函数声明中有意义的‘const‘