bcf*_*bcf 4 c++ pass-by-value copy-constructor return-by-value
这是一个简单的类头文件和一个主程序.在主程序中,我认为复制构造函数在三种情况下被调用:初始化(显式复制),函数参数的值传递,以及函数的值返回.然而,似乎它没有被其中一个调用,我认为评论中编号为(3)或(4).它被称为哪个数字(1) - (4)?谢谢.
XH:
#include <iostream>
class X
{
public:
X() {std::cout << "default constructor \n";}
X(const X& x) { std::cout << "copy constructor \n";}
};
Run Code Online (Sandbox Code Playgroud)
主要:
#include "X.h"
X returnX(X b) // (1) pass by value - call copy constructor?
{
X c = b; // (2) explicit copy - call copy constructor?
return b; // (3) return by value - call copy constructor?
}
int main()
{
X a; // calls default constructor
std::cout << "calling returnX \n\n";
X d = returnX(a); // (4) explicit copy - call copy constructor?
std::cout << "back in main \n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
default constructor
calling returnX
copy constructor
copy constructor
copy constructor
back in main
Run Code Online (Sandbox Code Playgroud)
由于复制经常在C++中发生,并且因为它可能很昂贵,所以允许编译器忽略某些复制(和移动)结构.即使被删除的构造函数和/或析构函数具有类似程序输出的副作用,也允许使用此复制省略(也就是说,它不是真正的优化,因为有和没有复制省略的行为是不同的).
根据12.8 [class.copy]第31段,有四个可以应用复制省略的基本位置:
return直接返回与函数的返回类型具有相同类型的局部变量的语句中.throw语句中,try当抛出对象时,可以省略最内层块中的自动变量的副本.catch子句按值捕获对象并且与throw语句中的对象具有相同的类型时,可以省略该副本.确切的规则稍微复杂一点,但我认为这是它的要点.鉴于复制省略的规则相当严格,很容易抑制复制省略:最简单的方法是使用一个identity()函数:
template <typename T>
T const& identity(T const& object) {
return object;
}
...
X d = identity(returnX(a));
Run Code Online (Sandbox Code Playgroud)
(这个版本也禁止移动构造;使用a推导类型T&&并适当地返回它应该使移动构造成为可能,但我不太确定返回类型和返回语句应该是什么).
| 归档时间: |
|
| 查看次数: |
258 次 |
| 最近记录: |