C++ 为什么const X&可以通过功能进行修改?

C++ Why can const X& be modified by function?

本文关键字:修改 功能 可以通过 为什么 const C++      更新时间:2023-10-16

在另一篇文章中,我测试了函数中关于const X& x的示例。这个链接"const X&X"是什么意思?说"这意味着x对x对象进行别名,但您不能通过x更改x对象。"但下面的示例显示我们可以修改x对象?为什么?

#include <iostream>
using namespace std;
int a = 1;
void DoWork(const int &n)
{
a = n * 2;  // If n was a reference to a, n will have been doubled
cout << "n: " << n << endl;
//f();  // Might change the value of whatever n refers to
}
int main()
{
DoWork(a);
cout << "a: " << a << endl;
}

后续问题:例如,我们有一个返回常量引用的函数,为什么它可以分配给非常量引用?

const X& tmp = get();
X& other = tmp; //this works, but why? this get rids of const X& in tmp?

我认为您对const和引用感到困惑。首先,什么是参考`

它是对象的另一个名称(别名(。

关于函数参数中所写的内容意味着n是一个常量引用。这意味着您不能更改an。(或者在简单意义上,n不能在赋值运算符的左侧。它也意味着n永久地与对象有界。

n = n+2; // This is an error as n is const and hence you can't use n to modify the object it is pointing.
a = n+2; // here you are not using `n` to modify. So this is ok.
int x = 10 ;
n = x; // error as n is bounded to `a` so it can't be bounded again to any other variable x. You can see `n` is on left which is an error.

现在,如果你做这个

cout<<a<<"t"<<n<<endl; // Output 3; (1+2)

关于后续问题。(仔细阅读(让我们假设一个一般情况。

const int ci = 1024;
int &r2 = ci;  // error: non const reference to a const object

你的函数问题也是如此。你一定在想我们为什么不能做这样的事。看这里c1是const,所以我们不能更改它。现在假设(JUST suppose(下面的代码是合法代码。那么r2将是对c1的引用。现在,正如我所说,引用是一个对象的另一个名称。这意味着如果我们对r2进行算术运算,它将对ci进行运算。r = r+2; // it means ci = ci + 2 ;但看到ci是const(它不应该改变,但我们改变了它。(所以我们需要做一些类似的事情。

const int ci = 1024;
const int &r2 = ci;  // error: non-const reference to a const object

这确保了我们不能r = r +2;,保证/保持ci的恒定性

get((返回const,因此为了保持其const,用于从函数接收的变量必须是const。所以,根据标准,你所说的工作部分是错误的,可能是你的编译器扩展。

请记住,const X&本质上意味着编译器施加了限制,即您不能通过引用来更改值引用(正如您链接的页面所说(。引用引用的实际纯粹是在运行时确定的,编译器在看到行a = n * 2;时无法推断出您正在更改x引用的值。

,对代码进行一个小的更改可以帮助进行操作

#include <iostream>
using namespace std;
int a = 1;
int b = 1; // new variable
void DoWork(const int &n)
{
a = n * 2;  // If n was a reference to a, n will have been doubled
cout << "n: " << n << endl;
//f();  // Might change the value of whatever n refers to
}
int main()
{
// Whether `x` in `DoWork` refers to `b` or `a` is purely determined at runtime.
if (rand() % 2 == 0)
DoWork(a);
else
DoWork(b);
cout << "a: " << a << endl;
}

换句话说,编译器不能确定引用将指向什么值。在C++中,引用甚至可以指向无效内存

int *a = 0;
int &ref = *a;
cout << ref; // runtime error

希望这能有所帮助。

编辑:关于后续问题,您使用的是什么编译器?任何标准编译器都会拒绝编译代码。