为什么可以在构造函数中修改const成员?

Jos*_* D. 43 c++ initialization const c++11 c++14

我很好奇为什么const构件可以在构造函数中修改.

初始化中是否有任何标准规则可以覆盖成员的"常量"?

struct Bar {
    const int b = 5; // default member initialization
    Bar(int c):b(c) {}
};

Bar *b = new Bar(2); // Problem: Bar::b is modified to 2
                     // was expecting it to be an error
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

son*_*yao 66

这不是修改(或赋值),而是初始化.例如

struct Bar {
    const int b = 5; // initialization (via default member initializer)
    Bar(int c)
        :b(c)        // initialization (via member initializer list)
    {
        b = c;       // assignment; which is not allowed
    }
};
Run Code Online (Sandbox Code Playgroud)

const数据成员不能被修改或分配,但它可以(而且需要)通过成员初始化列表或默认成员初始化进行初始化.

如果在同一数据成员上提供了默认成员初始值设定项和成员初始值设定项,则将忽略默认成员初始值设定项.这就是为什么b->b用值初始化2.

如果成员具有默认成员初始值设定项并且也出现在构造函数的成员初始化列表中,则忽略默认成员初始值设定项.

另一方面,默认成员初始值设定项仅在成员初始值设定项列表中未指定数据成员时生效.例如

struct Bar {
    const int b = 5;   // default member initialization
    Bar(int c):b(c) {} // b is initialized with c
    Bar() {}           // b is initialized with 5
};
Run Code Online (Sandbox Code Playgroud)

  • 只是为了扩展这个"不修改(或赋值)"的语句:`Bar(int c):b(c){}`在第一次构造时初始化b,但是`Bar(int c){b = c; 在构造它的默认值为5之后,它将分配它.这就是`const`阻止的. (14认同)

Cás*_*nan 16

添加到songyuanyao的最佳答案,如果您想要一个const无法在构造函数中初始化的数据成员,您可以创建该成员static:

struct Bar {
    static const int b = 5; // static member initialization
    Bar(int c)
        :b(c)        // Error: static data member can only be initialized at its definition
    {
        b = c;       // Error: b is read-only
    }
};
Run Code Online (Sandbox Code Playgroud)

在C++ 17中,您可以通过以下方式进一步改进inline:

struct Bar {
    inline static const int b = 5; // static member initialization
    Bar(int c)
        :b(c)        // Error: static data member can only be initialized at its definition
    {
        b = c;       // Error: b is read-only
    }
};
Run Code Online (Sandbox Code Playgroud)

这样您就不会遇到ODR问题.