引用用法对C++的影响

Effects of reference usage in C++

本文关键字:影响 C++ 用法 引用      更新时间:2023-10-16

我正在阅读斯科特·迈耶斯(Scott Meyers)的《有效C++》,并遇到了这个。使用引用/指针的原因包含以下内容:

string s1("Nancy");
string s2("Clancy");
string& rs = s1; // rs refers to s1
rs = s2; //rs still refers to s1, but s1's value is now "Clancy".

所以,我尝试了这个:

string s1("Nancy");
string s2("Clancy");
string& rs = s1;
cout << rs << endl;
rs = s2;
cout << rs << endl;
cout << s1 << endl;

看到的输出:

nancy
clancy
clancy

这意味着 s1 的值现在已更改,并且s1 的原始值永远丢失了??

这是区分引用和指针的原因之一??仅当您确定不会在不同时间引用不同的对象时,才在指针上使用引用?

C++ 标准 n3337

§ 5.17 赋值和复合赋值运算符

2) 在简单赋值 (=) 中,表达式的值将替换 左操作数引用的对象。

(...

6) 当赋值运算符的左操作数表示引用时 到 T,操作分配给类型 T 的对象,该对象由 参考。

§ 8.5.3 参考文献

1)声明为T&或T&&的变量,即"对类型的引用" T"(8.3.2),应由T类型的对象或函数初始化 或者通过可以转换为 T(...) 的对象。

2) 在之后不能将引用更改为引用另一个对象 初始化。请注意,引用的初始化将被视为 与分配给它非常不同。参数传递 (5.2.2) 和 函数值返回 (6.6.3) 是初始化。

3) 初始值设定项只能在参数中省略以供引用 声明 (8.3.5),在函数返回类型的声明中,在 类成员在其类定义 (9.2) 中的声明, 以及显式使用外部说明符的位置。

不能在 C++ 1 中重新初始化引用。您可以为其引用的对象分配不同的值。对于该引用,这是永远的同一个对象。这就是你在示例中所做的。

string s1("Nancy")   // s1 Nancy
string s2("Clancy"); // s2 Clancy
string& rs = s1;     // rs-> s1
cout<<rs<<endl;      // ==cout s1
rs=s2;               // == s1=s2  
                     // s1 Clancy
                     // s2 Clancy
cout<<rs<<endl;      // ==cout s1
cout<<s1<<endl;
这意味着 s1

的值现在已更改,并且 s1 的原始值为 永远失去??

是的。

这是区分引用和指针的原因之一 然后?

是的。指针可以重新初始化,而引用不能。这是这里指出的第一个区别

在C++中,指针变量和引用变量有什么区别?

何时使用引用与指针

仅在不重新初始化指针时使用引用?

当您希望始终指向同一对象时,请使用它们。如果它是类的成员,并且您希望保留该类的有效对象始终包含对某物的引用的不变性,也可以使用它们。构造类实例时,必须始终初始化引用成员,以便引用强制您保留不变性。


1 正如 Kanze @James 在评论中指出的那样,您实际上不能以这个词的正确技术含义重新初始化C++中的任何内容。在大多数情况下,初始化涉及构造函数,并且 (ctor) 仅在对象生命周期开始时调用一次(在这种情况下,引用的初始化是特殊的,因为 § 8.5.3/2 指出该引用是通过从函数传递参数或返回值来初始化的)。发生这种情况后,只有一个赋值,即调用 T& operator=(T const&)

以简单而简短的方式回答您的问题....的,"S1"的原始值"丢失"在确实发生了变化。为什么?创建引用变量时,将创建一个变量,该变量将具有另一个变量作为别名。此引用变量将保留别名变量的地址。这就像有一个指针。R. 变量将始终指向 A. 变量。但是,指针和 R.Variable 之间的区别在于,对于指针,您以不同的方式取消引用,使用 R.Variable 时,您可以将它们视为普通变量,其次,对于 R.Variable,您不会像在指针中那样执行任何特殊操作来寻址其内存。

int AliasV = 70;
int& RefeV = AliasV;
cout<<RefeV <<" "<< AliasV;
//Now RefeV is addressing to AliasV memory. (Similar to Pointer but no equal)
RefeV = 100;
//Because RefeV is addressing to AliasV memory, AliasV now has as value 100
cout<<RefeV<<" "<<AliasV;

输出:

70 70
100 100

提示:

  • 请记住,RefeVariable 将始终在幕后寻址到其别名内存。
  • 对 RefeVariable 的任何更改都将影响其别名。