c++11的move操作

C++0x中加入了右值引用,和move函数。
通过move操作可以减少不必要的内存分配.c++ 对string,set等都加入了move操作,增加效率.
那如果我们自定义类的时候,如果类中的变量没有能move操作的变量,是否写了移动构造函数事没有效果的?
例子如下

#include <iostream>
#include <utility>
#include <vector>
#include <string>

using namespace std;

class MyPoint{
public:
    MyPoint()
        :comment(""), x(0), y(0)
    {
    }

    MyPoint(const MyPoint& p)
       :comment(p.comment),x(p.x),y(p.y) 
    {cout<<"copy is called"<<endl;}

    MyPoint(MyPoint&& p)
       :comment(move(p.comment)), x(move(p.x)), y(move(p.y))
    {
        cout<<"move is called"<<endl;
      //  p.x = 0;
       // p.y = 0;
    }

    string toString()
    {
        char buf[100];
        sprintf(buf, "%s: %d %d", comment.c_str(), x, y);

        return buf;
    }
    string comment;
    int x;
    int y;

};

int main()
{
    MyPoint p;
    p.comment = "First point";
    p.x = 9;
    p.y = 7;

    vector<MyPoint> v;
    MyPoint p1(std::move(p));
    cout<<p.x<<" "<<p.y<<endl;
    cout<<p.comment<<endl;
    cin.get();
}

结果:
move is called
9 7

comment的值被转移了,p的x,y还在
那,如果去除类中的comment属性,那么移动构造函数还有没有存在必要.

阅读 4.8k
2 个回答

没必要,基本类型本来就是值语义,
右值引用只是一种类型而已,编译器并不会为它增加什么额外的功能,
它的功能还是由你来定义了,如果你觉得没用,大可不必定义

是否写了移动构造函数事没有效果的?
如你测试所示, 利用std::move把变量p强制转化成右值引用, 会调用到移动构造函数.
但是有一点要注意, 这个强制转换效果和下面这个没啥两样:

MyPoint p1(static_cast<MyPoint&&>(p));

意思就是说使用的时候就把move当成一个强制转换的函数好了. 和原始类型是啥没多大关系.

只有对于类中管理了资源类的东西, 才有必要使用移动构造函数(内存/文件/数据库链接)

多说一句, 我理解这东西默认不用, 用之前得评估一下, 因为强转操作本身就不是对资源的管理进行转移,右侧的值要注意, 在移动构造的时候很可能已经被重置了, 后面继续用就会运行时挂掉.

比如你例子里面用一个标准的移动构造函数管理int *成员变量就不成了.

...
A(A&& a) : m_ptr(a.m_ptr) {
    a.m_ptr = nullptr; 
    cout<<"move construct"<<endl;
}  
...
A ma; 
//A mb(std::move(ma));
A mb(static_cast<A&&>(ma));
cout<<*ma.m_ptr<<endl;    // core了
...
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进