简体   繁体   English

声明对象和赋值运算符的引用

[英]Declaring a reference to object and the assignment operator

I feel like this question is basic enough to be out there somewhere, but I can't seem to be able to find an answer for it. 我觉得这个问题很基本,可以在某个地方出现,但我似乎无法找到答案。

Suppose I have this code: 假设我有这个代码:

//class member function
std::map< std::string, std::string > myMap;

const std::map< std::string, std::string >& bar()
{
   return myMap;
}

void myFunc( std::map< std::string, std::string >& foo1 )
{
   foo1 = bar();
   std::map< std::string, std::string >& foo2 = bar();
}

My understanding is that if I start using foo2, since foo2 is a reference to the same instance as what bar() returns, anything I do with foo2 will be reflected in myMap. 我的理解是,如果我开始使用foo2,因为foo2是对bar()返回的同一实例的引用,我用foo2做的任何事都将反映在myMap中。 But what about foo1? 但是foo1怎么样? Does foo1 get a copy of myMap or does it also point to the same instance as what bar() returns? foo1是否获得了myMap的副本,还是指向与bar()返回的实例相同的实例? The c++ standard library says that the assignment operator for std::map will copy the elements over, but then does that mean the assignment operator is not really invoked in the declaration of foo2? c ++标准库说std :: map的赋值运算符会复制元素,但这是否意味着在foo2的声明中没有真正调用赋值运算符?

Thanks! 谢谢!

References are not reseatable in C++. 引用在C ++中不可重用。 This means that once they're initialized, you can't reassign them. 这意味着一旦初始化,您就无法重新分配它们。 Instead, any assignment actually involve the referred object. 相反,任何赋值实际上都涉及被引用的对象。 So in your code, 所以在你的代码中,

foo1 = bar();
std::map< std::string, std::string >& foo2 = bar();

the first line calls std::map::operator= on the object that was passed as a parameter to myFunc . 第一行调用std::map::operator=作为参数传递给myFunc After that, foo1 stills refers to that same object -- but its value (eg what elements it holds) may very well has been changed. 在那之后, foo1 stills引用同一个对象 - 但它的值(例如它所拥有的元素)可能已经被改变了。

Note that the second line is not assignment if there ever was any doubt that it was in your mind. 请注意,如果怀疑它在您的脑海中,则第二行不是赋值。 Instead, it is an initialization. 相反,它是一个初始化。 Since the return type of bar is actually std::map<std::string, std::string> const& , it can't bind to std::map<std::string, std::string>& so it's a compile error. 由于bar的返回类型实际上是std::map<std::string, std::string> const& ,它不能绑定到std::map<std::string, std::string>&所以它是一个编译错误。


To expand on the 'philosophical' side of things, C++ references are designed to be as transparent as possible and don't really exist as objects. 为了扩展事物的“哲学”方面,C ++引用被设计为尽可能透明,并不像对象那样存在。 This is using the C++ Standard meaning of the term (it is not related to OOP): it means that for instance reference types do not have a size. 这是使用术语的C ++标准含义(它与OOP无关):它表示例如引用类型没有大小。 Instead, sizeof(T&) == sizeof(T) . 相反, sizeof(T&) == sizeof(T) Similarly, references do not have addresses and it's not possible to form a pointer or a reference to a reference: given int& ref = i; 类似地,引用没有地址,也不可能形成指针或对引用的引用:给定int& ref = i; , then &ref == &i . ,然后&ref == &i

References are thus purposefully meant to be used as if the referred objects were being used themselves. 因此,有意地使用引用,就像所引用的对象本身被使用一样。 The only thing reference-specific that happens in the lifetime of a reference is its initialization: what it can bind to and what it means in terms of lifetime. 在引用的生命周期中发生的唯一特定于引用的是它的初始化:它可以绑定到什么以及它在生命周期中意味着什么。

The line 这条线

foo1 = bar();

creates a copy (because that's what map 's assignment operator does). 创建一个副本(因为这是map的赋值运算符所做的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM