更改引用成员的成员 >当我运行 TestFrf()/Cuth>时,结果并不是我所期望的,如果C++引用实际上是对内存中相同点的引用: struct MyPOD{ float x; }; struct Agg{ MyPOD& m; Agg():m(MyPOD()){} }; void testRef(){ MyPOD p; p.x=15.5; Agg a; a.m=p; //referencing the object above qDebug()<<"a.m.x is: "<<a.m.x; //15.5 qDebug()<<"p.x is: "<<p.x; //15.5 a.m.x=5; qDebug()<<"a.m.x is: "<<a.m.x; //5 qDebug()<<"p.x is: "<<p.x; //15.5 } struct MyPOD{ 浮动x; }; 结构聚集{ MyPOD&m; Agg():m(MyPOD()){} }; void testRef(){ MyPOD p; p、 x=15.5; Agg a; a、 m=p;//引用上面的对象 qDebug()

更改引用成员的成员 >当我运行 TestFrf()/Cuth>时,结果并不是我所期望的,如果C++引用实际上是对内存中相同点的引用: struct MyPOD{ float x; }; struct Agg{ MyPOD& m; Agg():m(MyPOD()){} }; void testRef(){ MyPOD p; p.x=15.5; Agg a; a.m=p; //referencing the object above qDebug()<<"a.m.x is: "<<a.m.x; //15.5 qDebug()<<"p.x is: "<<p.x; //15.5 a.m.x=5; qDebug()<<"a.m.x is: "<<a.m.x; //5 qDebug()<<"p.x is: "<<p.x; //15.5 } struct MyPOD{ 浮动x; }; 结构聚集{ MyPOD&m; Agg():m(MyPOD()){} }; void testRef(){ MyPOD p; p、 x=15.5; Agg a; a、 m=p;//引用上面的对象 qDebug(),c++,C++,您的代码不会执行您认为它可以执行的操作。引用不是“可重新搜索的”。一旦它被绑定,您就无法更改它绑定到的内容 声明: a.m=p; 不使a.m引用p。它将p复制到a.m(与以前一样保持绑定) 注意到,代码> AGG的构造函数使用非标准扩展。不能将非const L值引用绑定到标准C++中的临时值,这将创建一个“悬空引用”,因为临时分配在分配后被破坏。.将我的评论放在回答中:引用不能反弹,在您的情况下,它绑定在构造函数中。它们必须绑定在构造函数初始值设定项列表中,至少在c++11之前,您在这里执行此

您的代码不会执行您认为它可以执行的操作。引用不是“可重新搜索的”。一旦它被绑定,您就无法更改它绑定到的内容

声明:

a.m=p;
不使
a.m
引用
p
。它将
p
复制到
a.m
(与以前一样保持绑定)


注意到,<>代码> AGG的构造函数使用非标准扩展。不能将非const L值引用绑定到标准C++中的临时值,这将创建一个“悬空引用”,因为临时分配在分配后被破坏。.

将我的评论放在回答中:引用不能反弹,在您的情况下,它绑定在构造函数中。它们必须绑定在构造函数初始值设定项列表中,至少在c++11之前,您在这里执行此操作:

Agg():m(MyPOD()){}
      ^^^^^^^^^^
您稍后要做的工作基本上是复制到已经绑定的变量中,这也会改变它引用的原始变量,但在您的情况下,这只是
MyPOD()

顺便说一句,这是一个临时变量,所以即使它目前看起来工作正常,也不要使用它。它不能保证继续工作。它实际上甚至没有在我的Archlinux上使用gcc 4.9进行编译,给出以下信息:

main.cpp:在构造函数“Agg::Agg()”中: main.cpp:12:19:错误:从“MyPOD”类型的右值初始化“MyPOD&”类型的非常量引用无效 Agg():m(MyPOD()){}

或clang 3.4版:

main.cpp:12:10:错误:对“MyPOD”类型的非常量左值引用无法绑定到“MyPOD”类型的临时 Agg():m(MyPOD()){} ^ ~~~~~~~ 生成1个错误

这意味着您不能从临时(右值)设置非常量引用

简而言之,你的评论是错误的:

Agg a;
a.m=p; //referencing the object above
这将是正确的评论:

Agg a;
a.m=p; //copying the object above by using the assignment operator
当你写作时:

Agg():m(MyPOD())
这应该无法编译,因为
MyPOD()
是一个临时对象,临时对象不能绑定到非常量引用

如果您的编译器允许,那么谁知道发生了什么,您就在编译器扩展的土地上。也许它允许此代码,但是当您稍后访问
m
时,行为是未定义的,并且它引用了一个已被破坏的对象


顺便说一句,代码
a.m=p;
调用
a.m.operator=(p)
,它不会“重置引用”或任何事情。

我很欣赏否决票,但我不确定这会如何改变问题的有效性。因此,我不建议任何明显的重复。引用不能反弹。它是在施工时绑定的。请查看。@herohuyongtao谢谢,我经常看到它这样说参考是c++对指针的改进,建议改用它"然而,我认为这是一个清楚的原因,为什么它们是具有不同用途的不同技术。我看不出有什么好的理由否决这个问题。如果这是一个真实的副本,那么这与仅仅删去引用(这也是一个副本)有何不同?我认为引用应该避免开销。@OpenLearner:你不知道什么是引用是,是吗?它引用的是另一件事,而基于值的变量则不是。当您稍后更改此处的引用时,您也会更改原始的…这是一个副本分配。如果您在聚合中删除引用,则会有不同的语义-
a.m
从不引用其他内容。这不是问题效率,但语义问题。此外,您的代码是无效的,您不能像在
Agg
@Mat的构造函数中那样将成员绑定到临时对象。谢谢,代码编译并运行良好,因此不确定“无效”,但基于此信息,我同意这肯定不是“明智的”@OpenLearner:是否有可能使用MSVC?GCC和clang error out(正确)。VisualStudio有一个非标准的扩展,允许这样做(我相信)。