前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则C.48:如果构造函数需要用常数初始化成员,使用类内初始化器更合适

C++核心准则C.48:如果构造函数需要用常数初始化成员,使用类内初始化器更合适

作者头像
面向对象思考
发布2020-03-25 16:12:59
6500
发布2020-03-25 16:12:59
举报
文章被收录于专栏:C++核心准则原文翻译

C.48: Prefer in-class initializers to member initializers in constructors for constant initializers

C.48:如果构造函数需要用常数初始化成员,使用类内初始化器更合适

Reason(原因)

Makes it explicit that the same value is expected to be used in all constructors. Avoids repetition. Avoids maintenance problems. It leads to the shortest and most efficient code.

明确表示希望所有的构造函数都使用相同的值。避免维护问题。可以生成最短,最高效的代码。

Example, bad(反面示例)

代码语言:javascript
复制
class X {   // BAD
    int i;
    string s;
    int j;
public:
    X() :i{666}, s{"qqq"} { }   // j is uninitialized
    X(int ii) :i{ii} {}         // s is "" and j is uninitialized
    // ...
};

How would a maintainer know whether j was deliberately uninitialized (probably a poor idea anyway) and whether it was intentional to give s the default value "" in one case and qqq in another (almost certainly a bug)? The problem with j (forgetting to initialize a member) often happens when a new member is added to an existing class.

维护人员怎么才能知道 j 是否是故意没有初始化(尽管这可能是坏主意)呢?怎么知道一种情况将s初始化为“”,而另一种情况初始化为"qqq"是有意而为之呢(这几乎就是一个错误)?关于 j 的问题(忘了初始化某个成员)经常发生在向类添加新成员的时候。

Example(示例)

代码语言:javascript
复制
class X2 {
    int i {666};
    string s {"qqq"};
    int j {0};
public:
    X2() = default;        // all members are initialized to their defaults
    X2(int ii) :i{ii} {}   // s and j initialized to their defaults
    // ...
};

Alternative(可选方案)

We can get part of the benefits from default arguments to constructors, and that is not uncommon in older code. However, that is less explicit, causes more arguments to be passed, and is repetitive when there is more than one constructor:

通过使用构造函数的默认参数,我们可以得到某些好处。这种情况在老代码中可以说很常见。然而,这种做法缺乏明确性,会导致更多的参数被传递,并且在多于一个构造函数存在时导致代码重复,很麻烦。

代码语言:javascript
复制
class X3 {   // BAD: inexplicit, argument passing overhead
    int i;
    string s;
    int j;
public:
    X3(int ii = 666, const string& ss = "qqq", int jj = 0)
        :i{ii}, s{ss}, j{jj} { }   // all members are initialized to their defaults
    // ...
};

Enforcement(实施建议)

  • (Simple) Every constructor should initialize every member variable (either explicitly, via a delegating ctor call or via default construction). (简单)所有的构造函数都应该初始化每个成员(可以明确地通过委托构造函数或默认构造函数)
  • (Simple) Default arguments to constructors suggest an in-class initializer may be more appropriate.
  • (简单)针对构造函数的默认参数使用类内初始化器可能是更加恰当的选择。

觉得本文有帮助?请分享给更多人。

关注【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档