在类中初始化字段的原因是什么?

时间:2016-02-23 15:50:27

标签: c++ class c++11 initialization

在C ++中,可以在课堂上初始化类的字段值,例如:

class X
{
  int a = 5;
}

它是什么原因?它有用吗?默认的ctor完全相同。似乎我无法使用位掩码(int a : 3)初始化值。

2 个答案:

答案 0 :(得分:8)

来自the authority(这与早期的标准提案N2756非常相似):

  

类内成员初始值设定项

     

在C ++ 98中,只能在类中初始化整数类型的静态const成员,并且初始化程序必须是常量表达式。这些限制确保我们可以在编译时进行初始化。例如:

     

int var = 7;

class X {
    static const int m1 = 7;        // ok
    const int m2 = 7;                   // error: not static
    static int m3 = 7;              // error: not const
    static const int m4 = var;          // error: initializer not constant expression
    static const string m5 = "odd"; // error: not integral type
    // ...
};
     

C ++ 11的基本思想是允许在声明它(在其类中)的地方初始化非静态数据成员。然后,构造函数可以在需要运行时初始化时使用初始化程序。考虑:

class A {
public:
    int a = 7;
};
     

这相当于:

class A {
public:
    int a;
    A() : a(7) {}
};
     

这节省了一些输入,但真正的好处来自具有多个构造函数的类。通常,所有构造函数都为成员使用公共初始值设定项:

class A {
public:
    A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {}
    A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {}
    A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {}
    int a, b;
private:
    HashingFunction hash_algorithm;  // Cryptographic hash to be applied to all A instances
    std::string s;                   // String indicating state in object lifecycle
};
     

hash_algorithm和s每个都有一个默认值的事实在代码混乱中丢失,并且在维护期间很容易成为问题。相反,我们可以将数据成员的初始化分解出来:

class A {
public:
    A(): a(7), b(5) {}
    A(int a_val) : a(a_val), b(5) {}
    A(D d) : a(7), b(g(d)) {}
    int a, b;
private:
    HashingFunction hash_algorithm{"MD5"};  // Cryptographic hash to be applied to all A instances
    std::string s{"Constructor run"};       // String indicating state in object lifecycle
};
     

如果成员由类内初始值设定项和构造函数初始化,则只完成构造函数的初始化(它"覆盖"默认值)。所以我们可以进一步简化:

class A {
public:
    A() {}
    A(int a_val) : a(a_val) {}
    A(D d) : b(g(d)) {}
    int a = 7;
    int b = 5;  
private:
    HashingFunction hash_algorithm{"MD5"};  // Cryptographic hash to be applied to all A instances
    std::string s{"Constructor run"};       // String indicating state in object lifecycle
};

答案 1 :(得分:3)

通常,您的类定义位于头文件(.h)中,您的构造函数位于实现文件(.cpp)中。

我曾多次看到一个错误,其中头文件有一长串成员变量,实现文件初始化它们......但是不小心跳过一个成员,导致错误。

在目视检查中,代码看起来正确。很多成员宣布;很多成员初始化。缺少单一价值并不明显。

通过将所有初始化放在与声明相同的位置,可以更容易地看到您是否忘记初始化一个成员。

class MySample
{

private:
    int m_CountSamples       { 0 };
    int m_SampleWidth        { sizeof(int) };
    double m_SamplePrecision { 3.14 };
    bool m_fieldIsSorted;                       // It is obvious which field got skipped!
    enumMeaning fieldMeaning { eProductionSample };
};