【问题标题】:Initialising class members - default values or member-init-list?初始化类成员 - 默认值或成员初始化列表?
【发布时间】:2019-09-10 16:11:06
【问题描述】:

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

抱歉,如果我从根本上误解了这里的某些内容。

【问题讨论】:

  • @Andreas:这个问题没有说明类定义中的默认值,这主要是这个问题的意义所在。
  • "什么时候应该使用成员初始化器列表,什么时候应该使用默认值" 使用任何对你来说更方便的东西,它们有效地做同样的事情。
  • 这不是关于您遇到的问题的问题,因此它与 SO 无关。无论如何,答案主要是基于意见的。我的回答是,作为一般经验法则,如果可以,请使用内联初始化。如果不能,请使用构造函数初始值设定项列表。如果不能,请在构造函数主体中赋值。
  • 这个问题对我来说似乎很切题。
  • @TonyK 当一个问题是关于 SO 的主题时,这意味着它应该可以用一个解决问题并且“正确”的答案来回答。我不认为这可以在这里实现。您可以根据人们的意见和编码风格得到不同的答案,并且无法客观地说哪些是“正确的”,哪些是“错误的”。

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


【解决方案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 的直接访问(大多数情况下不是一个好的选择,将其视为修改成员的更复杂方法的占位符)。如果无法访问实际的初始值设定项,您必须修改 一个对象。这使得m 对于BCDconstant 对象有效地成为编译时常量。如果可以使用初始化器列表(AB),则应避免构造函数主体(C)中的成员“初始化”(有时这不像此处显示的那么简单)。

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

所以A 似乎是最灵活的选择。但这不是初始化两个或更多成员的好模式:太容易混淆参数顺序。


[1]这个选项是在我(感谢NikosC)意识到这个选项存在之后添加的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多