我对这个引用指向两个不同对象的想法有什么不对?

时间:2013-09-13 10:15:25

标签: c++ pointers reference

我是C ++的新手,我正在努力寻找经常发现的语句(例如在http://yosefk.com/c++fqa/ref.html#fqa-8.1中),与指针相反,在初始化之后,你无法为另一个对象创建一个引用点。

我在这里有一个代码片段,在我看来,这完全是这样的:

std::string s1("Hello");
std::string s2("World");
std::string& refToS = s1;  // initialize reference to object 1
cout << refToS << endl;
refToS = s2;               // make reference point to object 2
cout << refToS << endl;    

输出为“Hello World”。

这可能是一个枯燥的问题,但我无法弄清楚我的误解是什么。

4 个答案:

答案 0 :(得分:2)

您所做的就是将s2分配给s1refToS仍指代s1

std::string s1("Hello");
std::string s2("World");
std::string& refToS = s1;  // initialize reference to object 1
cout << refToS << endl;
refToS = s2;               // assign s2 to the referent of refToS
cout << refToS << endl;    
cout << s1 << endl;
cout << s2 << endl;

输出

Hello
World
World
World

答案 1 :(得分:0)

refToS = s2;  // make reference point to object 2

此行不符合您的想法。这就像发生s2s1的任务一样。

您无法更改引用所指向的对象。

答案 2 :(得分:0)

引用它引用的对象。所以这段代码:

refToS = s2;

不符合您的想法。它实际上将s2分配给refToS个引用(即`s1)。所以,这一行实际上是这样做的:

s1 = s2;

执行后,s2s1都将等于“世界”

答案 3 :(得分:0)

虽然John已正确解释您实际上正在string::operator=(const string&)上调用s1,但更改s1并未重新引用该引用,我认为重要的是要指出FQA在这里是错误的。

可以将参考点指向另一个对象,即创建引用时甚至不存在的对象。

C ++标准具有以下规则:

  

如果在对象的生命周期结束之后,在重用或释放对象占用的存储之前,在原始对象占用的存储位置创建一个新对象,指针   指向原始对象,引用原始对象的引用,或者原始对象的名称将自动引用新对象,并且一旦生命周期为新对象已经开始,可以   用于操纵新对象,如果:

     
      
  • 新对象的存储空间正好覆盖原始对象占用的存储位置,   和
  •   
  • 新对象与原始对象的类型相同(忽略顶级cv限定符),
  •   
  • 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为const-qualified或引用类型的非静态数据成员,并且
  •   
  • 原始对象是类型为T的派生程度最高的对象,新对象是类型为T的派生程度最高的对象(即,它们不是基类子对象)。
  •   

简单来说,这意味着引用绑定到特定的内存位置,不能反弹到另一个内存位置。但是该内存位置的对象可以更改(一个的结束生命周期,开始另一个的生命周期),以便相同的引用可以访问多个不同的对象。

要做到这一点,请使用显式的析构函数调用(结束对象的生命,但释放内存),然后使用placement-new:

refToS.~string();
// refToS now refers to raw storage
new (&refToS) std::string("Creating a new string");

这与在s1上使用赋值运算符不同,结果是一个全新的std::string对象。

显然,说“参考是对象”是一种误解。此声明在概念上错误的另一个证据是,当对象超出范围时,析构函数会运行。当引用超出范围时,没有任何反应。引用是在初始化期间绑定到内存位置的句柄(就像const指针一样),并且作为句柄,它与对象本身不同。