声明对对象和赋值运算符的引用
Posted
技术标签:
【中文标题】声明对对象和赋值运算符的引用【英文标题】:Declaring a reference to object and the assignment operator 【发布时间】:2011-10-16 17:40:33 【问题描述】:我觉得这个问题足够基本,可以在某个地方找到,但我似乎无法找到答案。
假设我有这个代码:
//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();
我的理解是,如果我开始使用 foo2,因为 foo2 是对与 bar() 返回的相同实例的引用,所以我对 foo2 所做的任何事情都会反映在 myMap 中。但是 foo1 呢? foo1 是否获得了 myMap 的副本,或者它是否也指向与 bar() 返回的实例相同的实例? c++ 标准库说 std::map 的赋值运算符会将元素复制过来,但这是否意味着在 foo2 的声明中并未真正调用赋值运算符?
谢谢!
【问题讨论】:
【参考方案1】:引用在 C++ 中不可重新安装。这意味着一旦它们被初始化,就不能重新分配它们。相反,任何分配实际上都涉及被引用的对象。所以在你的代码中,
foo1 = bar();
std::map< std::string, std::string >& foo2 = bar();
第一行在作为参数传递给myFunc
的对象上调用std::map::operator=
。在那之后,foo1
Stills 指的是同一个对象——但它的值(例如它所包含的元素)很可能已经改变了。
注意第二行是不是的赋值,如果你有任何疑问的话。相反,它是一个初始化。由于bar的返回类型实际上是std::map<std::string, std::string> const&
,所以不能绑定到std::map<std::string, std::string>&
所以是编译错误。
为了扩展事物的“哲学”方面,C++ 引用被设计为尽可能透明,并不真正作为对象存在。这是使用该术语的 C++ 标准含义(它与 OOP 无关):这意味着例如引用类型 not 有大小。相反,sizeof(T&) == sizeof(T)
。同样,引用没有地址,也不可能形成指针或对引用的引用:给定int& ref = i;
,然后是&ref == &i
。
因此,引用是有意使用的,就像被引用的对象被自己使用一样。在引用的生命周期中发生的唯一特定于引用的事情是它的初始化:它可以绑定到什么以及它在生命周期中的含义。
【讨论】:
+1 谢谢,我自己学到了一些新东西。我刚刚做了一个测试,我确实 100% 错了,你是对的 =-) 好的,太好了!谢谢,我真正需要知道的是赋值运算符是在 foo1 中调用的,而不是在 foo2 中调用的。很好的解释,谢谢! @Luc 如果可能的话,你能复习一下为什么一般不使用引用变量吗?我对它们是什么有了更好的理解(感谢您的回答),但似乎编码人员通常更喜欢指针。是冗余吗?范围有限? @MannyD 我的经历和你的不一样。我经常使用引用并看到引用用作局部变量,对于这种用法,它们通常比指针更可取。 @Luc 我想我应该澄清一下。我一直在函数参数列表中看到/使用它们,但我不明白你为什么要在代码体中声明一个,甚至作为类成员。【参考方案2】:线
foo1 = bar();
创建一个副本(因为这是map
的赋值运算符所做的)。
【讨论】:
返回对全局变量的引用似乎很奇怪,不是吗? @0A0D:不是真的,它可以用于封装,如果“全局”变量实际上没有外部链接。或者您可以返回对全局变量a
或全局变量 b
的引用。以上是关于声明对对象和赋值运算符的引用的主要内容,如果未能解决你的问题,请参考以下文章