C++移动构造函数

对于了解移动构造函数的工作原理,我们需要在编译时设置编译选项-fno-elide-constructors以关闭返回值优化效果,从样就可以看到完整的移动构造函数调用过程,避免编译器优化,有些地方看不到调用移动构造函数的过程。-fno-elide-constructors这个参数只是针对C++的,手册对该参数的描述如下:

   -fno-elide-constructors
       The C++ standard allows an implementation to omit creating a
       temporary which is only used to initialize another object of the
       same type.  Specifying this option disables that optimization, and
       forces G++ to call the copy constructor in all cases.

大致意思是:C++标准允许一种(编译器)实现省略创建一个只是为了初始化另一个同类型对象的临时对象。指定这个参数(-fno-elide-constructors)将关闭这种优化,强制G++在所有情况下调用拷贝构造函数。

(在stackoverflow上有一个有关这个参数使用的问题https://stackoverflow.com/questions/27086573/when-and-why-would-i-use-fno-elide-constructors)

下面就一段代码进行分析。

使用g++ test.cpp -fno-elide-constructors -g -o .\.output\main.exe命令进行编译

运行结果:

construct      //这是A b时调用无参构造函数
move construct     //这是b初始化函数返回的临时对象时调用的移动构造函数
delete       //释放b对象
move construct  //将函数返回的临时对象初始化a时调用移动构造函数
delete  //释放函数返回的临时对象

当将移动构造函数注释掉,编译后运行结果为:

construct    /这是A b时调用无参构造函数
copy construct    //这是b初始化函数返回的临时对象时调用的拷贝构造函数
delete    //释放b对象
copy construct    //将函数返回的临时对象初始化a时调用拷贝构造函数(因为自定义了拷贝构造函数,因此编译器不会合成默认   移动构造函数)
delete   //释放掉函数返回的临时对象

当将移动构造函数和拷贝构造函数都注释掉,编译后运行结果为:

construct  //这是A b时调用无参构造函数
delete      //释放b对象
delete   //释放掉函数返回的临时对象

注意第三种情况使用的是编译器自己合成的拷贝构造函数。因为没有自己定义拷贝构造函数或者拷贝赋值运算符。这里由于自定义了析构函数,因此编译器不会合成默认的移动构造函数。具体的可以参考《C++ primer》第13章。

你可能感兴趣的:(C/C++)