我认为值得立即开始使用代码:
#include <iostream>
class C
{
public:
C(int a);
~C();
C(const C &rhs);
C& operator=(const C &rhs);
C(C &&rhs);
C& operator=(C &&rhs);
int _a;
};
void func(C a)
{
std::cout << a._a << std::endl;
}
int main()
{
func(C{1});
std::cout << "Exit" << std::endl;
return 0;
}
C 类实现所有自动生成的方法(构造函数、析构函数、构造函数和用于复制和移动的赋值运算符)。
方法的调试信息输出显示,对于传递给 func 函数(主函数的第一行)的对象,仅调用简单的构造函数。
这听起来像是一个愚蠢的问题,但这对我来说是一个启示。为什么没有调用复制操作?传递给 func 的参数只是“成为”函数本身的局部参数。一直都是这样,还是现代编译器的优化?
如果有的话,我使用的是支持 11 和 14 标准的 GNU g++ 6.3.1。
排除不必要的复制/移动操作是由于语言中存在所谓的复制/移动省略。在可用标准的在线草案中,这是15.8.3。它说在某些条件下允许从代码中抛出复制/移动构造函数的调用。
对于 gcc/clang 编译器,可以使用
-fno-elide-constructors.此外,值得注意的是,从 C++17 开始,提到的优化是强制性的,即使存在键也不会导致复制/移动:
C++14
C++17
编译器只是将这些简单的类优化到被解释为简单类型的程度。以下是编译器如何执行优化的示例:链接
顺便说一下,您的构造函数和移动运算符声明不正确:
右值不能是 const,添加 const 会自动将右值转换为 const 左值,即 您只需声明构造函数和复制运算符两次。