C++ C+中的常量对象、常量成员函数和可变变量+;

C++ C+中的常量对象、常量成员函数和可变变量+;,c++,function,constants,mutable,member-functions,C++,Function,Constants,Mutable,Member Functions,我知道const对象不能调用非const成员函数。在C++14标准(ISO/IEC 14882:2014)第9.3.2节第3段中有这样的说明: 仅当对象表达式的cv限定值等于或小于成员函数的cv限定值时,才能对对象表达式(5.2.5)调用cv限定值成员函数 如果成员函数不修改任何内容,此约束是否有意义?或者如果成员函数修改可变变量?例如: class My_Class { public: mutable int value; void function(

我知道
const
对象不能调用非
const
成员函数。在C++14标准(ISO/IEC 14882:2014)第9.3.2节第3段中有这样的说明:

仅当对象表达式的cv限定值等于或小于成员函数的cv限定值时,才能对对象表达式(5.2.5)调用cv限定值成员函数

如果成员函数不修改任何内容,此约束是否有意义?或者如果成员函数修改可变变量?例如:

class My_Class {
    public:
        mutable int value;
        void function( int x ) const { value = x; } //     Correct
      //void function( int x )       { value = x; } // Not Correct
        My_Class() : value(0) {}
};

int main(){

    const My_Class obj;
    obj.function( 1 );

    return 0;
}
在此特定情况下,如果函数为
const
,则程序正确,函数可以修改
const
对象的变量。如果函数不是常量,则程序不正确。所以最后,我需要编写
const
来修改某些内容,这应该与
const
的目的相反

有人知道为什么这个规则是这样设计的吗

如果成员函数未修改任何内容,[第9.3.2节,第3段]是否有意义?或者如果成员函数修改可变变量

是的。函数的调用方通常无法知道函数是否修改了任何不可变的成员。它知道函数是否为常量,因此编译器只能基于此做出决定

非常量函数可以修改非可变状态,因此显然不能在常量对象上调用它。非常量函数是否修改状态无关紧要,因为它是一个在决定是否允许调用时不可用的实现细节。换句话说,常量是函数接口的一部分,而函数的实现不是接口的一部分。函数的接口完全由其声明指定

例如:

struct C {
    mutable int a;
            int b;
    void do_something();
};

const C c;
c.do_something();
允许调用
执行某些操作有意义吗?
dou\u something
可能不会修改
b
这一事实是否会影响这一点?我们怎么能假定
做某事
不会修改
b

答案是:这毫无意义。它没有效果。我们不可能做出这样的假设

编写一个不修改任何不可变状态的非常量成员函数(至少可能修改或通过返回指向
this
的非常量引用/指针间接允许修改)没有什么意义,尽管标准允许这样做

所以最后,我需要编写const来修改一些东西,这应该与const的目的相反

这似乎有点矛盾,但那是因为它过于简单化了。您需要编写常量才能修改常量对象的可变状态。您编写的const声明您不修改任何不可变状态,并且该声明授予对const对象调用它的权限

注释掉的non-const函数仍然正确地用于non-const对象

如果成员函数未修改任何内容,[第9.3.2节,第3段]是否有意义?或者如果成员函数修改可变变量

是的。函数的调用方通常无法知道函数是否修改了任何不可变的成员。它知道函数是否为常量,因此编译器只能基于此做出决定

非常量函数可以修改非可变状态,因此显然不能在常量对象上调用它。非常量函数是否修改状态无关紧要,因为它是一个在决定是否允许调用时不可用的实现细节。换句话说,常量是函数接口的一部分,而函数的实现不是接口的一部分。函数的接口完全由其声明指定

例如:

struct C {
    mutable int a;
            int b;
    void do_something();
};

const C c;
c.do_something();
允许调用
执行某些操作有意义吗?
dou\u something
可能不会修改
b
这一事实是否会影响这一点?我们怎么能假定
做某事
不会修改
b

答案是:这毫无意义。它没有效果。我们不可能做出这样的假设

编写一个不修改任何不可变状态的非常量成员函数(至少可能修改或通过返回指向
this
的非常量引用/指针间接允许修改)没有什么意义,尽管标准允许这样做

所以最后,我需要编写const来修改一些东西,这应该与const的目的相反

这似乎有点矛盾,但那是因为它过于简单化了。您需要编写常量才能修改常量对象的可变状态。您编写的const声明您不修改任何不可变状态,并且该声明授予对const对象调用它的权限


您注释掉的非常量函数仍然正确地用于非常量对象。

您的问题中有一个基本的误解:

class My_Class {
    public:
        mutable int value;
        void function( int x )       { value = x; } // Absolutely fine
        My_Class() : value(0) {}
};

mutable
并不意味着“只能在
const
成员函数中修改”。这意味着“即使在
常量中也可以修改”

您的问题中存在一个基本的误解:

class My_Class {
    public:
        mutable int value;
        void function( int x )       { value = x; } // Absolutely fine
        My_Class() : value(0) {}
};
mutable
并不意味着“只能在
const
成员函数中修改”。它的意思是“即使在
常量中也可以修改”
成员函数

应用于非引用非常量类型的非静态类成员,并指定该成员不影响类的外部可见状态(通常用于互斥锁、备忘录缓存、延迟求值和访问指令)