class A { public: A( A&&a):m_a(a.m_a) { std::cout<<"move contruct:"<<m_a<<endl; } A(const A&a):m_a(a.m_a) { std::cout<<"copy contruct:"<<m_a<<endl; } A() { std::cout<<"contruct:"<<m_a<<endl; } A(int a):m_a(a) { std::cout<<"contruct:"<<m_a<<endl; } ~A() { std::cout<<"destruct:"<<m_a<<endl; } int m_a=8; }; #include <queue> int main() { std::queue< std::shared_ptr<A> > qa; std::shared_ptr<A> pa; { A a(77); // std::shared_ptr<A> pa (std::make_shared<A>(a) ); // pa = std::make_shared<A>(a); 调用的是拷贝构造函数 pa = std::make_shared<A>(std::move(a) );//调用的是移动构造函数 } A b = *pa.get(); qa.push(pa); return 0; }
1,对于没有指针的类来说(例如A,普通数据类型int,long等),其移动构造函数与拷贝构造函数都是一样的,所以用不用move都是一样。
2,make_share会重新构造一个对象,而不是指向局部变量a,所以不用担心a析构销毁后,pa变成野指针。
3,OBJ obj2 =std::move(obj);所执行的操作是:(1)将obj里面的指针赋值给obj2里面的指针,即:obj2.p=obj.p,那么新对象就可以用旧对象内部原来的内存了,不用自己重新new(即obj2就可以用obj里指针之前new的内存了),避免深拷贝。(2)将obj.p=nullptr。防止析构两次。
对于有指针的类来说,用不用move才有区别。move的作用就是避免临时变量的深拷贝,从而避免new两次析构两次:
有指针的类,默认拷贝函数是浅拷贝,为了避免重复删除,需要用户自定义一个深拷贝的拷贝构造函数(也就是new两次,两个对象的指针指向两份内存),而临时变量的深拷贝没有必要(new了又删,还不如让新对象的指针 指向临时对象的指针指向的内存,然后临时对象的指针变成空。就不会new和析构两次),通过move来优化,也就是延长临时对象里面指针指向的那个内存的生命周期来复用内存,防止new两次。
原文地址:http://mingtangduyao.blog.51cto.com/4876371/1741827