为什么我们不能在构造函数初始化列表中初始化静态变量,但我们可以在构造函数体中

why we can't initialize static variable in constructor initialization list , but we can in constructor body

我总是读到初始化列表比构造函数主体更适合变量初始化。我也知道静态变量可以在 class 之外初始化。

但我的问题是为什么我们不能在构造函数初始化列表中初始化静态变量,但我们可以在构造函数主体中初始化

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){}

报错。为什么?

在构造函数的主体中,您赋值初始化只能在初始化列表中完成。

你认为的初始化静态成员只是对它的赋值。您可以自己测试一下:创建静态成员const,您的构造函数将不再有效。

那么,构造函数初始化列表只适用于实例成员。但是,静态成员不是您 class 的 实例 的成员,而是与其他 class 成员具有相同可见性的全局变量;因此,在 class 初始化列表中对它们 "initialize" 的任何尝试实际上都是静态成员的 "re-initialization",这在 C++ 中是被禁止的。

成员初始化列表表示初始化static 成员已在程序开始时初始化(在 main 之前)。如果你能按照你的建议去做,你将成为 "re-initialising" 你创建的每个 sample 对象的静态成员,但对象只初始化一次。

相反,如果你想在对象初始化后改变它的值,你必须给它赋值。这正是您的第一个代码对 i = ii;.

所做的

您只能初始化一次,但构造函数可能 运行 多次。此外,您不应访问未初始化的内容。

假设这是允许的。然后你必须像这样回答有关代码的难题:

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);
}

有意义吗?您必须更改语言的哪些部分才能使它变得有意义 并且 不会造成危险的混淆?允许这种代码的哪些好处超过了增加的混乱和复杂性?答案按顺序是:不,太多了,根本就 none。