c++11 move是否真正生效

http://stackoverflow.com/questions/3106110/what-is-move-semantics/

解释了 move 语义。非常清楚。

我主要是想测试一下move语义是否真正生效了。

1. move构造函数在何种情况下会被调用

2. 编译器神马时候会合成默认的move构造函数

3. 对于包含了其他成员的类来说,对于被包含的对象来说,move语句在神马情况下是生效的。

比如说,B 中有 A 类型的对象,那么,在调用 B 的move构造函数的时候,A的move构造函数是否会被调用。


#include <iostream>

using namespace std;

class A {
public:
  A() {}
  A(const A& lv) { cout << "a copy ctor." << endl; }
  A(A&& rv) { cout << "a move ctor." << endl; }
};

class B {
public:
  B() {}
  B(int ia) {}
//  B(const B& lv) : a(lv.a) { cout << "b copy ctor." << endl; }             // 1
//  B(B&& rv) : a(std::move(rv.a)) { cout << "b move ctor." << endl; }       // 2
//  B(B&& rv) : a(rv.a) { cout << "b move ctor." << endl; }                  // 3
//  B(B&& rv) = default;                                                     // 4
private:
  A a;
};

int main() {
  B b;
  B b1(b);
  cout << "111" << endl;
  B b2(std::move(b));
}


以上程序在 g++ 4.8.1上编译

case A:

1,2,3,4全部被注释的输出结果:

a copy ctor.
111
a move ctor.

猜测原因:

编译器自己合成了B的copy和move构造函数,并且,在B的move构造函数中调用了A的move构造函数。


case B:

取消1的注释,2,3,4注释掉:

a copy ctor.
b copy ctor.
111
a copy ctor.
b copy ctor.

猜测原因:

编译器没有合成 B的默认move构造函数,并且,即使用户将变量 b std::move化,调用的也是B的copy构造函数。

因为用户自己定义了B的copy构造函数,所以编译器会认为,你自己管理了资源,所以就不敢随便编写一个move构造函数了。

cpp标准 12.8 节规定了编译器隐式定义move构造函数的条件:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf


case C:

取消1,2的注释,3,4注释掉:

a copy ctor.
b copy ctor.
111
a move ctor.
b move ctor.

猜测原因:

就是都定义了,所以调用对应的move或者copy而已。


case D:

取消1,3注释,2,4注释掉:

a copy ctor.
b copy ctor.
111
a copy ctor.
b move ctor.

猜测原因:

注意,在b的move构造函数中,调用的是a的copy构造函数。

这里的原因是 rv 的类型虽然是右值引用,但其自身是左值,如果要利用右值引用的优势,需要对 rv move化:

如改成这样就会调用 a 的 move 构造函数: B(B&& rv) : a(std::move(rv).a) { cout << "b move ctor." << endl; }

或者像例子 2 中的那样,对 rv 的每一个成员进行 move 化。



case E:

取消1,4的注释,2,3注释掉:

a copy ctor.
b copy ctor.
111
a move ctor.

猜测原因:

显示指定了move构造函数为default,此构造函数调用了a的move构造函数。


case F:

取消4的注释,只保留1,2,3:

编译不通过。


move_.cpp: In function ‘int main()’:
move_.cpp:26:9: error: use of deleted function ‘B::B(const B&)’
   B b1(b);
         ^
move_.cpp:12:7: note: ‘B::B(const B&)’ is implicitly declared as deleted because ‘B’ declares a move constructor or move assignment operator
 class B {

原因是因为已经定义 move 构造函数,所以copy构造函数默认声明为了 delete。

这个规则在cpp标准中也是规定了的。


啊,暂时先写这么点。。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值