检查我对功能返回的理解

时间:2014-07-02 21:09:23

标签: c++ function

作为一个新手,我发现在C ++书籍中从函数返回的解释相当神秘。

以下是我理解的摘要,希望有人能够纠正它:

前提:

T foo() {
   ...
   return expr;
}

main() {
   T var = foo();
}

我对回归过程的理解是否正确?

  1. expr的评估结果被隐式转换为声明的函数返回类型T。此转换发生在 foo();
  2. 上面的转换值用于初始化临时对象,比如“x”。子问题:第二次转换是在foo()还是main()中发生的?
  3. 临时对象“x”用于初始化main()中的变量var
  4. 欢迎任何输入!

3 个答案:

答案 0 :(得分:6)

让我们系统地解决这个问题。

如果函数声明为T f();,而T不是void,并且函数正常返回,则它必须通过{{1}形式的语句返回},其中return e;是表达式。

当您评估函数调用表达式e时,您将获得一个值。假设f()表示对象类型。如果UT = U &,则值为T = U &&,则表达式U必须能够绑定到引用,并且返回值为< / em> e的值。 (返回值也是所谓的&#34; glvalue&#34;,就其价值类别而言)。在这种情况下没有其他事情发生。函数调用的值是返回的东西。

然而,当e时,T = U的值是所谓的&#34; prvalue&#34; (a&#34;纯rvalue&#34;),这需要构建f()类型的临时对象。该对象的构造就像U一样(即从U obj = e隐式转换)。 e的值就是这个临时对象。它可以用于初始化另一个对象(例如f()),也可以绑定到引用(例如U x = f();)。

返回表达式U && r = f();与函数调用值的绑定是函数体范围内的最后一件事。值得注意的是,这是范围结束之前,即在范围本地对象被销毁之前。例如,如果在构造返回值对象期间抛出异常,则在异常传递给调用范围之前,必须发生范围展开以销毁本地对象。另一个有用的例子可能是使用范围防护装置,例如:互斥锁:

e

我们假设初始化U f() { std::locK_guard<std::mutex> lock(state_mutex); return state.get_value(); } 有意义,我们进一步假设U obj = state.get_value();只能在state.get_value()被锁定时调用。上面的代码正确而简洁地做到了这一点。

答案 1 :(得分:4)

  1. 你是对的,隐式转换发生在foo内。考虑当你有多个return语句并且每个语句返回不同的类型时 - 必须先转换所有这些类型,然后才能返回一个值。
  2. 没有第二次转换。第一次转换是临时建设或转让的一部分。
  3. 正确,除非以下说明。
  4. 许多编译器都会进行优化,称为copy elision,它会完全跳过临时文件。

答案 2 :(得分:2)

您的理解基本上是正确的。
可以有一些优化,因此没有那么多的步骤 复制。这可以是return value optimization
的形式 在c ++ 11中move semantics

关于你的子问题;
在自定义转换运算符,构造函数中,您应该假设 析构者等。