我总是读取初始化列表比构造函数体更适合初始化。我也知道静态变量可以在类外部进行初始化。
但我的问题是为什么我们不能在构造函数初始化列表中初始化静态变量,但我们可以在构造函数体中
class sample
{
static int i;
public:
sample (int ii=20) { i=ii;}
void show()
{
cout << i << endl;
}
};
int sample::i=12;
int main()
{
sample s;
s.show();
return 0;
}
工作正常并打印20.但我用
替换构造函数sample (int ii=20): i(ii){}
它给出了错误。为什么呢?
答案 0 :(得分:5)
在构造函数体内,您分配。 初始化只能 在初始化列表中完成。
您认为初始化静态成员只是对它的赋值。您可以自己测试:创建静态成员const
,您的构造函数将不再有效。
然后,构造函数初始化列表仅适用于实例成员。但是,静态成员不是您的类的实例的成员,而是与其他类成员具有相同可见性的全局变量;因此,任何在类初始化列表中“初始化”它们的尝试实际上都是静态成员的“重新初始化”,这在C ++中是被禁止的。
答案 1 :(得分:4)
成员初始化列表表示初始化。 static
成员已在程序开头(main
之前)初始化。如果你可以按照你的建议行事,那么你将使用你创建的每个sample
对象“重新初始化”静态成员,但对象只会被初始化一次。
相反,如果要在初始化对象后更改对象的值,则必须为其分配。这正是您的第一个代码使用i = ii;
执行的操作。
答案 2 :(得分:0)
您只能初始化一次,但构造函数可能会运行多次。此外,您不应该访问未初始化的内容。
假设允许这样做。然后你必须回答有关这样的代码的疑难问题:
int foo::static_member;
foo::foo() : static_member(42){}
foo::foo(int a) : static_member(a) {}
foo::foo(double b) {}
int main()
{
std::cout << foo::static_member;
foo m(2.5);
}
有意义吗?您需要更改哪些语言部分才能理解和不会造成危险的混乱?允许这种代码的好处超过了增加的混乱和复杂性?答案将是,顺序:不,太多,不打扰,根本没有。