移动构造函数和移动赋值运算符

如果第二个对象是在复制或赋值结束后被销毁的临时对象,则调用移动构造函数和移动赋值运算符,这样的好处是避免深度复制,提高效率

为了直观地观察移动构造函数和移动赋值运算符的运行方式,编写一个类Pointer,该类的对象会在堆动态创建一个数组。

代码如下:

[cpp]  view plain  copy
  1. class Pointer  
  2. {  
  3. public:  
  4.     Pointer(const int i,const string &n)  
  5.     {   
  6.         mptr = new int[i];   
  7.         length = i;  
  8.         name = n;  
  9.         cout <<"带参数构造函数\n";  
  10.         showID();   
  11.     }  
  12.     Pointer() :mptr(nullptr), length(0){ cout << "无参数构造函数\n"; showID(); }  
  13.     virtual ~Pointer()  
  14.     {  
  15.         cout <<name+ "析构函数\n";  
  16.         if (mptr)  
  17.             delete[] mptr;  
  18.         mptr = nullptr;  
  19.           
  20.     }  
  21.       
  22.     Pointer(const Pointer& s)  
  23.     {  
  24.         length = s.getlen();  
  25.         mptr = new int[length];   
  26.         name = s.name;  
  27.         cout << "复制构造函数\n";  
  28.         showID();  
  29.     }  
  30.     Pointer& operator=(const Pointer &s)  
  31.     {  
  32.         if (this == &s)  
  33.             return *this;  
  34.         if (mptr)  
  35.             delete[] mptr;  
  36.         length = s.getlen();  
  37.         mptr = new int[length];  
  38.         name = s.name;  
  39.         cout << "赋值运算符\n";  
  40.         showID();  
  41.         return *this;  
  42.     }  
  43.       
  44.     //移动构造函数,参数s不能是const Pointer&& s,因为要改变s的成员数据的值  
  45.     Pointer(Pointer&& s)  
  46.     {  
  47.         length = s.getlen();  
  48.         mptr = s.getmptr();  
  49.         name = s.name + "_yidonggouzao";//调用移动构造函数时,加一个标记  
  50.         s.mptr = nullptr;         
  51.         cout << "移动构造函数\n";  
  52.         showID();  
  53.     }  
  54.   
  55.     //移动赋值运算符  
  56.     Pointer& operator=(Pointer&& s)  
  57.     {  
  58.         if (this == &s)  
  59.             return *this;  
  60.         if (mptr)  
  61.             delete[] mptr;  
  62.         length = s.getlen();  
  63.         mptr = s.mptr;  
  64.         name = s.name+"_yidongfuzhi";//调用移动赋值运算符时,加一个标记  
  65.         s.mptr = nullptr;         
  66.         cout << "移动赋值运算符\n";  
  67.         showID();  
  68.         return *this;  
  69.     }  
  70.   
  71.     void showID()  
  72.     {   
  73.         cout << "长度:" << length<<"  指针:"<< mptr <<"  名字:"<<name<< endl;  
  74.     }  
  75.   
  76.     int getlen() const  
  77.     {  
  78.         return length;  
  79.     }  
  80.   
  81.     int* getmptr()const  
  82.     {  
  83.         return mptr;  
  84.     }  
  85.   
  86. private:  
  87.     int* mptr;  
  88.     int length;  
  89.     string name="#NULL";//该参数用来标记不同的对象,c++11支持直接在类的数据成员定义处初始化  
  90. };  
  91.   
  92. Pointer test()  
  93. {  
  94.     Pointer a(2,"test");  
  95.     return a;  
  96. }  
  97.   
  98. int _tmain(int argc, _TCHAR* argv[])  
  99. {  
  100.     //加花括号是为了观察析构函数的调用  
  101.     {  
  102.         Pointer(4,"notname1");  
  103.   
  104.         Pointer a1=test();//调用移动构造函数,创建对象a1  
  105.         cout << "a1.showID():\n";  
  106.         a1.showID();  
  107.   
  108.         Pointer a2;  
  109.         a2=Pointer(5, "notname2");//调用移动赋值运算符  
  110.           
  111.         Pointer a3(Pointer(7, "notname3"));//此处没有调用移动构造函数,也就是说Pointer(7, "notname3") 这个变量没有被立即销毁(即不是临时变量),也许是因为它有了名字a3,所以不是临时变量了  
  112.           
  113.         cout << "a3.showID():\n";  
  114.         a3.showID();//验证a3确实是Pointer(7, "notname3")  
  115.     }  
  116.   
  117.     cout << endl;  
  118.     system("pause");      
  119.     return 0;  
  120. }  


运行结果如下:



转载:http://blog.csdn.net/bupt8846/article/details/43833151

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值