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

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(反面示例)

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(示例)

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:

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

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.

  • (简单)针对构造函数的默认参数使用类内初始化器可能是更加恰当的选择。


觉得本文有帮助?欢迎点赞并分享给更多的人。

阅读更多更新文章,请关注微信公众号【面向对象思考】

发布了408 篇原创文章 · 获赞 653 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/craftsman1970/article/details/104541262
今日推荐