C++中的Const对象、Const成员函数和可变变量
Const Object, Const Member Function and Mutable Variable in C++
我知道 const
对象不能调用非 const
成员函数。它在 C++14 标准 (ISO/IEC 14882:2014) 第 9.3.2 节第 3 段中是这样说的:
A cv-qualified member function can be called on an object-expression (5.2.5) only if the object-expression is as cv-qualified or less-cv-qualified than the member function.
如果成员函数不修改任何东西,这个约束有意义吗?或者如果成员函数修改了一个可变变量?例如:
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
的相反目的。
有谁知道为什么这条规则是这样设计的?
Does [Section 9.3.2, Paragraph 3 of] make sense if the member function does not modify anything? Or if the member function modifies a mutable variable?
是的,确实如此。函数的调用者通常无法知道函数是否修改了任何非可变成员。它知道函数是否为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 引用/指针间接允许此类修改 - 没有什么意义,尽管标准确实允许这样做。
So in the end, I need to write const to be able to modify something, which should be the opposite purpose of const.
这似乎有些矛盾,但那是因为它过于简单化了。您需要编写 const 才能修改 const 对象的可变状态 。您编写的 const 声明您不修改任何非可变状态,并且该声明授予在 const 对象上调用它的权限。
您的 commented-out non-const 函数仍然可以正确用于 non-const 个对象。
你的问题存在根本性的误解:
class My_Class {
public:
mutable int value;
void function( int x ) { value = x; } // Absolutely fine
My_Class() : value(0) {}
};
mutable
并不代表 "can only be modified in a const
member function"。意思是"can be modified even in a const
member function".
mutable
关键字,
Applies to non-static class members of non-reference non-const type and specifies that the member does not affect the externally visible state of the class (as often used for mutexes, memo caches, lazy evaluation, and access instrumentation). mutable members of const class instances are modifiable
您在质疑 C++ 关键字的有效性。我觉得这个定义中的例子,提供了这样一个关键字的积极证据,并且mutable
语言的设计者所想象的对我们来说是一个福音。
我知道 const
对象不能调用非 const
成员函数。它在 C++14 标准 (ISO/IEC 14882:2014) 第 9.3.2 节第 3 段中是这样说的:
A cv-qualified member function can be called on an object-expression (5.2.5) only if the object-expression is as cv-qualified or less-cv-qualified than the member function.
如果成员函数不修改任何东西,这个约束有意义吗?或者如果成员函数修改了一个可变变量?例如:
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
的相反目的。
有谁知道为什么这条规则是这样设计的?
Does [Section 9.3.2, Paragraph 3 of] make sense if the member function does not modify anything? Or if the member function modifies a mutable variable?
是的,确实如此。函数的调用者通常无法知道函数是否修改了任何非可变成员。它知道函数是否为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 引用/指针间接允许此类修改 - 没有什么意义,尽管标准确实允许这样做。
So in the end, I need to write const to be able to modify something, which should be the opposite purpose of const.
这似乎有些矛盾,但那是因为它过于简单化了。您需要编写 const 才能修改 const 对象的可变状态 。您编写的 const 声明您不修改任何非可变状态,并且该声明授予在 const 对象上调用它的权限。
您的 commented-out non-const 函数仍然可以正确用于 non-const 个对象。
你的问题存在根本性的误解:
class My_Class {
public:
mutable int value;
void function( int x ) { value = x; } // Absolutely fine
My_Class() : value(0) {}
};
mutable
并不代表 "can only be modified in a const
member function"。意思是"can be modified even in a const
member function".
mutable
关键字,
Applies to non-static class members of non-reference non-const type and specifies that the member does not affect the externally visible state of the class (as often used for mutexes, memo caches, lazy evaluation, and access instrumentation). mutable members of const class instances are modifiable
您在质疑 C++ 关键字的有效性。我觉得这个定义中的例子,提供了这样一个关键字的积极证据,并且mutable
语言的设计者所想象的对我们来说是一个福音。