这些表单之间是否有任何区别:returnType vs returnType&?

Naw*_*waz 4 c++ reference return-type return-value

考虑这些免费的独立功能:

          std::vector<int>& f();   //reference
          std::vector<int>  g();   //value

/*const*/ std::vector<int>&  f1 = f();  //reference
          std::vector<int>   f2 = f();  //value

/*const*/ std::vector<int>&  g1 = g();  //reference
          std::vector<int>   g2 = g();  //value
Run Code Online (Sandbox Code Playgroud)

之间有什么区别:

  • f()和g().这是一个简单的问题,但我仍然希望听到一些关于它们的详细评论,因为它可能有助于理解下一个问题的答案.

  • f1和f2.它们是否与f()中的原始对象相同,或者f2将是原始的副本?取消评论const会有什么不同吗?

  • g1和g2.它们是否与g()中的原始对象相同,或者g2是原始的副本?取消评论const会有什么不同吗?

如果f()g()是成员函数,每个返回成员数据,而不是一些局部变量?它会对上述问题的答案产生任何影响吗?

请尝试在答案中包含所有陷阱和重点,并且不要考虑RVO或编译器的任何其他优化.我想知道C++是什么,而不是编译器做什么.如果你谈论优化,请明确提及它,这样我就不会将语言功能与编译器功能混合在一起.

Jam*_*lis 8

f()返回对象的引用; 从它返回不会复制任何对象. g()返回一个对象的副本,至少在概念上.

std::vector<int>&  f1 = f();  //reference
Run Code Online (Sandbox Code Playgroud)

f1指向f()返回引用的对象.没有制作副本.引用的const限定在这里没有区别(就复制而言;显然它会影响对象可以做什么).

std::vector<int>   f2 = f();  //value
Run Code Online (Sandbox Code Playgroud)

f2f()返回引用的对象的副本.

std::vector<int>&  g1 = g();  //reference
Run Code Online (Sandbox Code Playgroud)

这是无效的.非const引用不能绑定到临时对象.

如果引用常量限定,那么这条线是有效相同的下一行:由返回的对象的副本g()是由,参考被绑定到该副本,该副本被赋予基准的寿命(它当引用被"销毁"时被销毁.

std::vector<int>   g2 = g();  //value
Run Code Online (Sandbox Code Playgroud)

g2是由返回的对象的副本g().是否制作副本(以及可以制作多少副本)取决于编译器优化.

如果f()g()是成员函数,每个返回成员数据,而不是一些局部变量?

如果f()返回对局部变量的引用,则程序不正确并且如果您尝试使用该引用则会产生未定义的行为,因为当函数返回时,引用的对象不再存在.

如果f()返回对成员变量,动态分配的对象或具有静态或线程本地存储持续时间的对象的引用,则该引用对该对象的生命周期(或在同一位置构造的同一类型的另一个对象)有效在内存中作为返回引用的对象,尽管其实用性仅限于少数情况).

什么g()返回并不重要,因为总是制作副本(至少在概念上).