对于何时以及如何在构造函数中初始化类的成员,我有些困惑。如果我理解正确,则可以通过在类定义中包括默认值,构造函数成员初始化列表或通过在构造函数主体中进行赋值来实现。我意识到最好在进入构造函数的主体之前进行初始化,但是什么时候应该使用成员初始化程序列表,什么时候应该使用默认值?
很抱歉,如果我从这里根本误解了一些东西。
答案 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
的用法与B
,C
和D
的用法不同。
仅A
提供了一种使用默认值以外的值初始化m
的方法。所有变体都提供对m
的直接访问(通常不是一个好选择,将其视为占位符,以更复杂的方式修改成员)。如果无法访问初始构造器的实际值,则必须修改一个对象。这使得m
,B
和C
的常量对象的D
有效地成为了编译时常量。如果可以使用初始化器列表(C
或A
),则应避免构造器主体(B
)中的成员“初始化”(有时并不像这里所示的那么琐碎)。
如果使用的是C ++ 11或更高版本,则应该估算选项D
。
因此A
似乎是最灵活的选择。但这不是初始化两个或多个成员的好方法:混淆参数顺序太容易了。
[1] 在我(感谢NikosC)意识到该选项存在之后添加了该选项