什么是常量引用? (不是对常量的引用)

为什么常量引用的行为方式与常量指针不同,这样我就可以真正改变它们所指向的对象?它们看起来真的像是另一个普通的变量声明。我为什么要用它们?

这是我运行的一个简短示例,它编译并运行时没有错误:

int main (){
int i=0;
int y=1;
int&const icr=i;
icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
icr=99;         // Can assign another value but the value is not assigned to y...
int x=9;
icr=x;
cout<<"icr: "<<icr<<", y:"<<y<<endl;
}
139992 次浏览

语句 icr=y;不使引用引用 y; 它将 y的值赋给 icr引用的变量 i

引用本质上是 const,也就是说您不能更改它们所引用的内容。有一些“ const引用”实际上是“对 const的引用”,也就是说你不能改变它们引用的对象的值。它们被声明为 const int&int const&而不是 int& const

什么是常量引用(不是对常量的引用)
经常参考实际上是 对常数的引用

常数引用/常数引用表示如下:

int const &i = j; //or Alternatively
const int &i = j;
i = 1;            //Compilation Error

它基本上意味着,您不能修改引用所引用的类型对象的值。
例如:
试图通过常量引用修改变量 j的值(指定 1) ,i将导致错误:

只读引用‘ i’的赋值


icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
icr=99;

不更改引用,而是 任务引用的类型的值。 引用不能引用初始化时绑定到的变量以外的任何其他变量。

第一个语句 任务的值 yi
第二个语句 任务的值 99i

我猜你说的“常量引用”实际上是指“对常量数据的引用”。另一方面,指针可以是一个常量指针(指针本身是常量,而不是它指向的数据) ,一个指向常量数据的指针,或者两者兼而有之。

最清楚的答案。 “ X & const X”有意义吗?

不,这是无稽之谈

要了解上述声明的含义,请从右至左阅读: “ x 是对 X 的常量引用”,但这是多余的ーー引用 总是常量,在这个意义上,你永远不能重新安置一个参考 使它指向一个不同的对象。永远不要。有或没有 康斯特。

换句话说,“ X & const x”在功能上等同于“ X & x”。 因为在 & 后面添加 const 不会获得任何结果 不应该添加它: 它会使人们感到困惑ーー常量会使一些 人们认为 X 是 const,就好像你说的是 const X & x。

首先,我认为 int&const icr=i;只是 int& icr = i,修饰符‘ const’没有意义(它只是意味着你不能引用其他变量)。

const int x = 10;
// int& const y = x; // Compiler error here

其次,常量引用只是意味着不能通过引用改变变量的值。

const int x = 10;
const int& y = x;
//y = 20; // Compiler error here

第三,常量引用可以绑定右值。编译器将创建一个临时变量来绑定引用。

float x = 10;
const int& y = x;
const int& z = y + 10;
cout << (long long)&x << endl; //print 348791766212
cout << (long long)&y << endl; //print 348791766276
cout << (long long)&z << endl; //print 348791766340

这个代码格式不正确:

int&const icr=i;

参考文献: C + + 17[ dcl.ref ]/1:

除了引入 cv 限定符之外,Cv 限定引用都是格式不正确的 通过使用 Typedef-nameDectype 指定符,在这种情况下,cv 限定符被忽略。

这个规则已经出现在 C + + 的所有标准化版本中,因为代码是格式不正确的:

  • 你不应该使用它,而且
  • 没有相关的行为。

编译器应该拒绝程序; 如果不拒绝,那么可执行文件的行为就是完全未定义的。

注意: 不知道为什么其他的答案都没有提到这一点... ... 没有人能够访问编译器?

正如它在另一个答案中提到的,引用本质上是常量。

int &ref = obj;

一旦使用对象初始化了引用,就不能将此引用与它引用的对象解除绑定。引用就像化名一样。

当您声明一个 const引用时,它只不过是一个引用一个 const 对象的引用。

const int &ref = obj;

上面的声明性句子,如 constint,决定了引用所引用的对象的可用特性。为了更清楚地说明,我想向您展示 pointer等价于 const参考;

const int *const ptr = &obj;

因此,上面这行代码的工作方式相当于 const引用。另外,还有最后一点我想提一下;

只能使用对象初始化引用

所以当你这样做的时候,你会得到一个错误;

int  &r = 0; // Error: a nonconst reference cannot be initialized to a literal

这条规则有一个例外。如果引用被声明为 const,那么您也可以使用文本初始化它;

const int  &r = 0; // a valid approach