我知道const
对象无法调用非const
成员函数。它在C ++ 14标准(ISO / IEC 14882:2014)第9.3.2节第3段中这样说:
只有当object-expression与成员函数一样是cv-qualified或less-cv-qualified时,才能在object-expression(5.2.5)上调用 cv-qualified 成员函数
如果成员函数没有修改任何内容,这个约束是否有意义?或者如果成员函数修改了一个可变变量?例如:
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
来修改某些内容,这应该是const
的相反目的。
有谁知道为什么这条规则是这样设计的?
答案 0 :(得分:2)
如果成员函数没有修改任何内容,那么[第9.3.2节,第3段]是否有意义?或者如果成员函数修改了一个可变变量?
是的,确实如此。函数的调用者通常不能知道函数是否修改任何非可变成员。它知道函数是否为const,因此编译器只能根据它做出决定。
非const函数可以修改非可变状态,所以你显然不能在const对象上调用它。非const函数是否确实修改状态是无关紧要的,因为它是在决定是否允许调用时不可用的实现细节。换句话说,constness是函数接口的一部分,而函数的实现不是接口的一部分。函数的接口由其声明完全指定。
一个例子:
struct C {
mutable int a;
int b;
void do_something();
};
const C c;
c.do_something();
允许通话do_something
是否有意义? do_something
可能无法修改b
的事实是否会影响到这一点?我们怎么能认为do_something
不会修改b
?
答案是:它没有意义。它没有效果。我们无法做出这样的假设。
编写一个不会修改任何非可变状态的非const成员函数 - 至少可能通过返回非this
的非const引用/指针间接地允许或允许这种修改 - 尽管标准允许这样做。
所以最后,我需要编写const来修改一些东西,这应该是const的相反目的。
这似乎是矛盾的,但那是因为它过于简单了。您需要编写const才能修改 const对象的可变状态。你编写的const声明你不修改任何非可变状态,并且该声明允许在const对象上调用它。
您的注释掉的非const函数仍然可以与非const对象一起使用。
答案 1 :(得分:2)
你的问题存在根本性的误解:
class My_Class {
public:
mutable int value;
void function( int x ) { value = x; } // Absolutely fine
My_Class() : value(0) {}
};
mutable
并不意味着“只能在const
成员函数中进行修改”。这意味着“可以在const
成员函数中修改甚至”。
答案 2 :(得分:1)
mutable
关键字
适用于非引用非const类型的非静态类成员,并指定该成员不影响类的外部可见状态(通常用于互斥,备忘录缓存,延迟评估和访问检测) 。 const类实例的可变成员是可修改的
您质疑C ++关键字的有效性。我觉得这个定义中的例子提供了需要这样一个关键词的正面证据,并且语言设计者想象的mutable
对我们来说是一个福音。