初始化类成员-默认值还是member-init-list?

时间:2019-04-20 21:33:26

标签: c++ default-value initializer-list default-constructor member-initialization

对于何时以及如何在构造函数中初始化类的成员,我有些困惑。如果我理解正确,则可以通过在类定义中包括默认值,构造函数成员初始化列表或通过在构造函数主体中进行赋值来实现。我意识到最好在进入构造函数的主体之前进行初始化,但是什么时候应该使用成员初始化程序列表,什么时候应该使用默认值?

很抱歉,如果我从这里根本误解了一些东西。

1 个答案:

答案 0 :(得分:1)

您确实使事情有些混乱。至少有4个不同的概念

您制造了3个。

在以下示例中,at ideone.com我使用struct而不是class来简化/简单地使用内联构造函数。

#include <iostream>

struct A 
{ 
    A(int v=1): m(v) {}
    int m; 
};

struct B
{ 
    B(): m(2) {}
    int m; 
};

struct C
{ 
    C()
    {
        m = 3;
    }
    int m; 
};

// since C++11
struct D
{ 
    int m = 11; 
};

int main()
{
    using namespace std;
    #define TRACE(arg) cout << #arg ": " << arg.m << endl; 
    A a1;
    TRACE(a1)
    A a2(4); 
    TRACE(a2)
    B b;
    TRACE(b)
    b.m = 5;
    TRACE(b)
    C c;
    TRACE(c)
    c.m = 6;
    TRACE(c)
    D d;
    TRACE(d)
    d.m = 0;
    TRACE(d)
    #undef TRACE
}

A的用法与BCD的用法不同。

A提供了一种使用默认值以外的值初始化m的方法。所有变体都提供对m的直接访问(通常不是一个好选择,将其视为占位符,以更复杂的方式修改成员)。如果无法访问初始构造器的实际值,则必须修改一个对象。这使得mBC常量对象的D有效地成为了编译时常量。如果可以使用初始化器列表(CA),则应避免构造器主体(B)中的成员“初始化”(有时并不像这里所示的那么琐碎)。

如果使用的是C ++ 11或更高版本,则应该估算选项D

因此A似乎是最灵活的选择。但这不是初始化两个或多个成员的好方法:混淆参数顺序太容易了。


[1] 在我(感谢NikosC)意识到该选项存在之后添加了该选项