C++复制构造函数,临时函数和复制语义

leg*_*s2k 17 c++ variable-assignment copy-constructor compiler-optimization temporaries

对于这个计划

#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;
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

Entered f()!
Default C called!
CC called!
Run Code Online (Sandbox Code Playgroud)

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

dir*_*tly 14

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

查找返回值优化.这是默认打开的.如果您使用MSVC 2005+在Windows上,您可以使用/Od它关闭并获得所需的结果(或-fno-elide-constructors在GCC上).此外,对于MSVC,请参阅文章.

12.8复制类对象

15当满足某些条件时,允许实现省略类对象的复制结构,即使该对象的复制构造函数和/或析构函数具有副作用.在这种情况下,实现将省略的复制操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象被销毁的时间的晚期.优化.1515在以下情况下允许复制操作的省略(可以组合使用以消除多个副本):

- 在具有类返回类型的函数的return语句中, 当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象的名称时,通过构造自动化可以省略复制操作将对象直接转换为函数的返回值 - 在throw-expression中,当操作数是非易失性自动对象的名称时,可以通过直接构造自动对象来省略从操作数到异常对象(15.1)的复制操作进入异常对象

- 当一个未绑定到引用(12.2)的临时类对象被复制到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到省略的目标中来省略复制操作复制

- 当异常处理程序的异常声明(第15节)声明一个相同类型的对象(cv-qualification除外)作为异常对象(15.1)时,通过将异常声明视为一个异常声明,可以省略复制操作如果除了为exception-declaration声明的对象执行构造函数和析构函数之外,程序的含义将保持不变,则为异常对象的别名.

注意:强调我的