14 September 2022

C++ 核心指南目录

“Define a constructor if a class has an invariant”

理由

这是构造函数的目的。

例如

class Date {  // a Date represents a valid date
              // in the January 1, 1900 to December 31, 2100 range
    Date(int dd, int mm, int yy)
        :d{dd}, m{mm}, y{yy}
    {
        if (!is_valid(d, m, y)) throw Bad_date{};  // enforce invariant
    }
    // ...
private:
    int d, m, y;
};

最好通过构造函数来表达某种固定结构。

注意

就算类中没有固定结构,为了使用方便,也会用到构造函数。

例如

struct Rec {
    string s;
    int i {0};
    Rec(const string& ss) : s{ss} {}
    Rec(int ii) :i{ii} {}
};

Rec r1 {7};
Rec r2 {"Foo bar"};

注意

很多情况下,用了 C++11 的初始化列表,就不需要构造函数了。

比如

struct Rec2{
    string s;
    int i;
    Rec2(const string& ss, int ii = 0) :s{ss}, i{ii} {}   // redundant
};

Rec2 r1 {"Foo", 7};
Rec2 r2 {"Bar"};

Rec2 的构造函数就是多余的了。这个构造函数中 ii 的默认值,最好在成员定义的时候进行初始化。

强化

  • 标记那些有自定义的复制操作,却没有构造函数的类。自定义的复制造作意味着类中有某种固定结构。