有关该程序

#include <iostream>
using std::cout;

struct C 
{
    C() { cout << "Default C called!\n"; }
    C(const C &rhs) { cout << "CC called!\n"; }
};

const C f()
{
    cout << "Entered f()!\n";
    return C();
}

int main()
{
    C a = f();
    C b = a;

    return 0;
}

输出I得到的是:

Entered f()!
Default C called!
CC called!

由于f()由返回值,则它应该返回一个暂时的。由于T a = x;T a(x);,是不是要求a建设的拷贝构造函数,使用临时传入作为参数?

有帮助吗?

解决方案

  

由于f()由返回值,则它应该返回一个暂时的。由于T a = x;T a(x);,是不是要求a建设的拷贝构造函数,使用临时传入作为参数?

查找返回值优化。这是默认开启。如果你是在Windows上使用MSVC 2005+可以使用/Od关闭这个功能,并得到想要的结果(或GCC -fno-elide-constructors)。此外,对于MSVC看到文章。

  

<强> 12.8复制类对象

     

<强> 15 :当满足特定条件时,一个   实现是允许省略   复制一个类对象的结构,   即使拷贝构造函数和/或   析构函数为对象具有侧   效果。在这种情况下,   实施将源和   靶向省略复制操作的   因为根本就是两个不同的方式   指代相同的对象,并且   该对象的破坏发生在   时代后,当这两个   对象必须   被摧毁,而不   optimization.115一份,省音   操作被允许在   下列情况下(其可以是   组合以消除多个   份):

     

- 在返回在一份声明   与类返回类型功能,   当表达式是一个的名称   与非挥发性自动对象   相同CV-不合格类型作为   函数返回类型,拷贝   操作可以通过省略   构成自动对象   直接进入函数的返回   值    - 当在一抛表达,   操作数是一个名   非易失性自动目的,   从操作到操作复制   异常对象(15.1),可以省略   通过构建自动对象   直接进入异常对象

     

-   当具有一个临时的类对象   没有被结合到一个参考(12.2)   将被复制到一个类对象与   同样的CV-不合格的类型,拷贝   操作可以通过省略   构建临时对象   直接进入的目标   省略复制

     

- 当   异常的异常声明   处理程序(第15)中声明的对象   相同类型的(除   CV-资质)作为异常   对象(15.1),在复制操作罐   通过处理被省略   异常声明为的别名   如果意义的异常对象   该计划将是不变的除外   对构造的执行和   为对象的析构函数的声明   例外声明。

     

注意:重点矿

其他提示

这是的的返回值优化(RVO)功能,你的编译器支持。

的示例

一个拷贝构造函数可能不会当您返回值被调用。

在使用GCC -fno-elide-constructors选项关闭该功能。

我相信这就是所谓的返回值优化

我假定当f()返回C的对象是在调用方法因此没有复制需要初始化C a的堆栈空间分配的对象。这是你的default C called

C b = a

这导致拷贝构造因此你CC called

顺便说一句,在wiki上的例子看起来挺像类似代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top