C ++复制构造函数,临时和复制语义 [英] C++ Copy constructor, temporaries and copy semantics

查看:225
本文介绍了C ++复制构造函数,临时和复制语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此计划

  #include< iostream> 
using std :: cout;

struct C
{
C(){cout< 默认C调用!\\\
; }
C(const C& rhs){cout<< CC叫!\\\
; }
};

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

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

return 0;
}

我得到的输出是:

 输入f()! 
默认C调用!
CC调用!

由于 f() ,它应该返回一个临时的。 T a = x; 是 T a(x); ,不会调用复制构造函数构造 a ,临时传入作为其参数?

解决方案

blockquote>

由于 f()按值返回,它应该返回一个临时的。 T a = x; 是 T a(x); ,不会调用复制构造函数构造 a ,临时传入的参数为


查找返回值优化。默认情况下已启用。如果你在Windows上使用MSVC 2005+,你可以使用 / Od 将其关闭并获得所需的结果(或 -fno-elide-constructors 在GCC上)。此外,对于MSVC,请参阅文章。 / p>


12.8复制类对象



15 当满足某些标准时,
实现允许省略类对象

复制构造,即使复制构造函数和/或
析构函数为对象有边
效果。在这种情况下,
实现将忽略复制操作
的源和
目标视为两种不同的
引用同一对象的方式,
该对象的销毁发生在
,在更晚的时间,两个
对象将
销毁没有
优化.115这个复制
操作的精度是允许在
以下情况(可能
结合,以消除多个
副本):



- 语句在
函数中具有类返回类型

当表达式是
的名称时具有
的非易失性自动对象具有相同的cv非限定类型作为
函数返回类型,复制
操作可以通过
省略构造自动对象
直接到函数的返回
value
- 在a throw-expression,当
操作数是
非易失性自动对象的名称时,从操作数到
异常对象(15.1)的
复制操作可以省略
通过将自动对象
直接构造为异常对象



-
当具有
的临时类对象不被绑定到一个引用(12.2)
将被复制到一个类对象与
相同的cv非限定类型,复制
操作可以通过
省略构造临时对象
直接进入
省略副本的目标



- 当异常
异常声明时
处理程序条款15)声明一个相同类型的对象
(除了
cv-qualification)作为异常
对象(15.1),复制操作可以通过处理
异常声明作为
的别名如果
的意义为
,程序将保持不变,除了
用于执行构造函数和
析构函数用于对象


$

b $ b

For this program

#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;
}

the output I get is:

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

Since f() is returning by value, it should return a temporary. As T a = x; is T a(x);, wouldn't it call the copy constructor for the construction of a, with the temporary passed-in as its argument?

解决方案

Since f() is returning by value, it should return a temporary. As T a = x; is T a(x);, wouldn't it call the copy constructor for the construction of a, with the temporary passed-in as its argument?

Look up Return Value Optimization. This is turned on by default. If you are on Windows using MSVC 2005+ you can use /Od to turn this off and get the desired result (or -fno-elide-constructors on GCC). Also, for MSVC see this article.

12.8 Copying class objects

15 When certain criteria are met, an implementation is allowed to omit the copy construction of a class object, even if the copy constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization.115 This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):

in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type, the copy operation can be omitted by constructing the automatic object directly into the function’s return value — in a throw-expression, when the operand is the name of a non-volatile automatic object, the copy operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object

— when a temporary class object that has not been bound to a reference (12.2) would be copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary object directly into the target of the omitted copy

— when the exception-declaration of an exception handler (Clause 15) declares an object of the same type (except for cv-qualification) as the exception object (15.1), the copy operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration.

Note: Emphasis mine

这篇关于C ++复制构造函数,临时和复制语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆