C++ 中引用使用的影响

Effects of reference usage in C++

我正在阅读 Scott Meyers 的 Effective C++ 并偶然发现了这个。相互使用 references/pointers 的原因如下:

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++ Standard n3337

§ 5.17 Assignment and compound assignment operators

2) In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.

(...)

6) When the left operand of an assignment operator denotes a reference to T, the operation assigns to the object of type T denoted by the reference.

§ 8.5.3 References

1) A variable declared to be a T& or T&&, that is, “reference to type T” (8.3.2), shall be initialized by an object, or function, of type T or by an object that can be converted into a T.(...)

2) A reference cannot be changed to refer to another object after initialization. Note that initialization of a reference is treated very differently from assignment to it. Argument passing (5.2.2) and function value return (6.6.3) are initializations.

3) The initializer can be omitted for a reference only in a parameter declaration (8.3.5), in the declaration of a function return type, in the declaration of a class member within its class definition (9.2), and where the extern specifier is explicitly used.

您不能在 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;

That means s1's value is now changed and The original value of s1 is lost forever??

是的。

This is one of the things that differentiates references from pointers then?

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

What are the differences between a pointer variable and a reference variable in C++?

When to use references vs. pointers

Use references over pointers only when not reinitialising it?

当您希望始终指向同一个对象时使用它们。如果它是 class 的成员并且您想保留一个不变量,即 class 的有效对象始终包含对某物的引用,则也可以使用它们。在构造 class 实例时,必须始终初始化引用成员,这样引用会强制您保持不变。


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

以简单而简短的方式回答您的问题.... 原始值 s1”是“lost”中的真正改变。 为什么? 当您创建一个引用变量时,您正在创建一个将另一个变量作为别名的变量。该引用变量将保留别名变量的地址。这就像有一个指针。 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 的任何更改都会影响其别名。