关于const引用(和const指针)的弱语义
这可能已经被问到了。
为什么允许向非常量变量分配对常量的引用?
为什么这是允许的
int mut {0};
const int & r_to_c {mut};
mut = 1;
// now r_to_c changed to 1!
// But it was supposed to be a reference to something constant!
?
当然,我不能改变引用到常量本身的值。我不能
r_to_c = 2;
但是是不是const执行的资格太少了?我希望,从 const-ness 的承诺来看,不允许绑定到可变变量。
否则const给我什么保证?它们看起来很弱,而且这似乎很容易诱使程序员用脚射击自己。
我知道 C++ 以允许人们用脚射击自己而闻名。允许危险的事情发生我没有问题。在这种情况下,我的问题是,在这种情况下,它似乎是故意欺骗,因为const这里的语义不是人们所期望的。
我的问题是关于编译器和语言语义的问题,而不是特别关于引用的问题(我可以使用分配给非常量变量地址的常量指针来问同样的问题。像int mut{0}; const int * p_to_c{&mut};)。
为什么引用常量(或常量指针)的语义只是“你不能使用这个特定的窗口来修改你看到的东西(但如果你有其他非常量的窗口,你可以修改它)”而不是更强大的“这只能是声明为常量并且编译器保证它保持不变的东西的窗口”?
[术语说明:我使用表达式“const 引用”而不是“const 引用”,因为“const 引用”被解释为T& const- 与调用T* const“const 指针”一致 - 不存在。]
回答
但是 const 限定是不是执行得太少了?我希望,从 const-ness 的承诺来看,不允许绑定到可变变量。
不,这不是“太少”。你期待错了。
首先,你是否绑定了一个 const 引用并不会使对象本身const。那会很奇怪:
void foo(int& x) {
static const int& y = x;
}
当我打电话时foo:
int x = 42;
foo(x);
我不知道其他人是否会保留const对我的非常量的引用x。
否则 const 给我什么保证?
您不能通过const引用修改某些内容:
void bar(const int& x);
int x = 0;
bar(x);
当我调用一个接受 a 的函数时,const&我知道它不会修改我的(非常量)参数。如果 const 引用不会绑定到非常量对象,那么就无法使最后一个示例工作,即您只能将非常量对象传递给修改它们的函数,而不是传递给不修改它们的函数。
PS我能理解你的困惑。有时会忽略持有常量引用并不意味着不能修改对象。考虑这个例子:
#include <cstddef>
#include <iostream>
struct foo {
const int& x;
};
int main() {
int y = 0;
foo f{x};
std::cout << f.x; // prints 0
y = 42;
std::cout << f.x; // prints 42
}
将成员的值打印到屏幕会产生两种不同的结果,即使foo::x是一个常量引用!它是“常量引用”而不是“常量引用”。这里的const实际含义:您y不能通过f.x.