关于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.


以上是关于const引用(和const指针)的弱语义的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>