• std::move与vector的emplace_back使用笔记


    直接上代码

      1 /*
      2  * 本测试目的:
      3  *     1)验证使用vector的emplace_back是否真能提高效率;
      4  *     2)c++11默认的拷贝构造、移动构造都是浅拷贝,
      5  *        且默认的移动构造与默认的拷贝构造完全一样,
      6  *        所以如果要使用move语义提高效率,就必须手动实现移动构造,
      7  *        在移动构造中使用浅拷贝即可,但切不要忘记对原对象的指针设置为nullptr;
      8  *     3)对于有指针的对象,一定要手动实现其拷贝构造函数,不然使用浅拷贝,
      9  *        在使用stl容器的时候很容易调用默认的拷贝构造,造成double delete的情况;
     10  *     4)如果不对移动构造加上noexcept关键字,在使用vector等容器进行扩容的时候,
     11  *        会默认使用拷贝构造而不是移动构造,会降低效率;
     12  *
     13  * 总结:
     14  *    在编写含有指针的类的时候:
     15  *      1)手动实现拷贝构造进行深拷贝;
     16  *      2)手动实现移动构造进行浅拷贝,且将原对象的指针设为nullptr;
     17  *      3)对手动实现的移动构造一定要记得加上noexcept关键字;
     18  */
     19  
     20 #include <iostream>
     21 #include <vector>
     22 
     23 namespace my_test_c11_test {
     24 struct st_test {
     25   int a=0;
     26   int b=0;
     27 };
     28 
     29 typedef st_test TX;
     30 
     31 class EmplaceTest {
     32  public:
     33   EmplaceTest() {
     34     pstr_ = new TX; 
     35 
     36     std::cout<<"EmplaceTest constructor...	pstr_="<<pstr_<<"
    ";
     37   }
     38 
     39   ~EmplaceTest() {
     40     std::cout<<"~EmplaceTest deconstructor...	x="<<x<<"
    ";;
     41     if (pstr_) {
     42       std::cout<<"deconstructor  pstr_="<<pstr_<<"
    ";
     43       delete[] pstr_;
     44     }
     45   }
     46 
     47   EmplaceTest(const EmplaceTest& rhs) :
     48       x(rhs.x) {
     49     pstr_ = new TX;    // 此处一定要深拷贝
     50     pstr_->a = rhs.pstr_->a;
     51     pstr_->b = rhs.pstr_->b;
     52 
     53     std::cout<<"EmplaceTest copy constructor...	x="<<x<<"	pstr_="<<pstr_<<"
    ";
     54   }
     55 
     56   EmplaceTest(EmplaceTest&& rhs) noexcept:  // noxecpt关键字一定要加上,不然stl容器扩容的时候不会调用此移动构造,不能提升效率
     57     x(rhs.x),
     58     pstr_(rhs.pstr_)  {  // 为提高效率,此处浅拷贝即可
     59     std::cout<<"EmplaceTest move constructor...	x="<<x<<"	pstr_="<<pstr_<<"
    ";
     60     rhs.pstr_ = nullptr;  // 切记将原对象指针设为nullptr
     61   }
     62 
     63 
     64   EmplaceTest& operator=(const EmplaceTest& rhs) {
     65     std::cout<<"operator=...
    ";
     66     if (this == &rhs) {
     67       return *this;
     68     }
     69     x = rhs.x;
     70 
     71     if (pstr_) {
     72       delete pstr_;
     73       pstr_ = nullptr;
     74     }
     75     pstr_ = new TX;    // 此处一定要深拷贝
     76     pstr_->a = rhs.pstr_->a;
     77     pstr_->b = rhs.pstr_->b;
     78   }
     79   EmplaceTest& operator=(EmplaceTest&& rhs) {
     80     std::cout<<"operator= move ...
    ";
     81     if (this == &rhs) {
     82       return *this;
     83     }
     84     x = rhs.x;
     85     pstr_ = rhs.pstr_;      // 为提高效率,此处浅拷贝即可,切记要将原指针设为nullptr
     86     rhs.pstr_ = nullptr;
     87   }
     88 
     89  public:
     90   int x = 0;
     91   TX* pstr_ = nullptr;
     92 
     93 
     94 };
     95 
     96 
     97 }
     98 
     99 int main(void) {
    100   std::vector<my_test_c11_test::EmplaceTest> vtTest;
    101   //vtTest.reserve(10);
    102 
    103   for (int i=0; i<5; ++i) {
    104     my_test_c11_test::EmplaceTest tmp;
    105     tmp.x=i+1;
    106 
    107     vtTest.emplace_back(std::move(tmp));
    108   }
    109 
    110   std::cout<<"
    end=============================================================================
    
    ";
    111 
    112   return 0;
    113 }

    运行结果如下:

  • 相关阅读:
    切换路由时中止未返回数据的请求
    elementui 走马灯图片自适应
    覆盖elementui样式
    vue+elementui搭建后台管理界面(5递归生成侧栏路由)
    vue+elementui搭建后台管理界面(4使用font-awesome)
    vue+elementui搭建后台管理界面(3侧边栏菜单)
    vue+elementui搭建后台管理界面(2首页)
    vue+elementui搭建后台管理界面(1登录)
    C排序算法
    各种语言中获取时间戳的方法
  • 原文地址:https://www.cnblogs.com/guoliushui/p/10191605.html
Copyright © 2020-2023  润新知