在 C++ 中声明一个 const 对象需要一个用户定义的默认构造函数。如果我有一个可变成员变量,为什么不呢?

jin*_*ong 8 c++ clang++

在 C++ 中,要声明具有成员变量 as 的类的对象const,我们必须有一个用户定义的默认构造函数。下面的代码说明了这一点。

class Some {
    int value;
};

int main() {
    // error: default initialization of an object of const type 'const Some'
    //        without a user-provided default constructor
    const Some some;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果类拥有的成员变量被限定为可变的,编译器将不会报告任何错误。作为参考,我使用命令编译clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug。我想知道这个结果是由于编译器中的错误还是根据C++语言中定义的语法。

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mos*_*ieb 3

重写我的评论作为答案,希望它可以帮助别人。

\n\n

如果 const 对象没有以某种形式初始化,那么声明它是没有意义的。
\n考虑以下代码:

\n\n
    const int x;\n
Run Code Online (Sandbox Code Playgroud)\n\n

铿锵说:error: default initialization of an object of const type 'const int'
\n gcc会说:error: uninitialized const \xe2\x80\x98x\xe2\x80\x99 [-fpermissive]

\n\n

其背后的逻辑是这种类型的声明没有任何意义。
\n 的值x永远不会改变,因此该代码将是不可预测的,因为x会映射到未初始化的内存。
\n在您的示例中,添加关键字mutabletovalue意味着虽然Some实例在声明为时是常量:

\n\n
    const Some some;\n
Run Code Online (Sandbox Code Playgroud)\n\n

value以后还是有可能改变的。
\n例如:

\n\n
    some.value = 8;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着可以以可预测的方式使用此代码,因为value可以稍后设置,并且不存在未初始化的常量。

\n