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...\tpstr_="<<pstr_<<"\n";
 37   }
 38 
 39   ~EmplaceTest() {
 40     std::cout<<"~EmplaceTest deconstructor...\tx="<<x<<"\n";;
 41     if (pstr_) {
 42       std::cout<<"deconstructor  pstr_="<<pstr_<<"\n";
 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...\tx="<<x<<"\tpstr_="<<pstr_<<"\n";
 54   }
 55 
 56   EmplaceTest(EmplaceTest&& rhs) noexcept:  // noxecpt关键字一定要加上,不然stl容器扩容的时候不会调用此移动构造,不能提升效率
 57     x(rhs.x),
 58     pstr_(rhs.pstr_)  {  // 为提高效率,此处浅拷贝即可
 59     std::cout<<"EmplaceTest move constructor...\tx="<<x<<"\tpstr_="<<pstr_<<"\n";
 60     rhs.pstr_ = nullptr;  // 切记将原对象指针设为nullptr
 61   }
 62 
 63 
 64   EmplaceTest& operator=(const EmplaceTest& rhs) {
 65     std::cout<<"operator=...\n";
 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 ...\n";
 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<<"\nend=============================================================================\n\n";
111 
112   return 0;
113 }

 

 

运行结果如下:

 

posted @ 2018-12-28 16:56  郭流水  阅读(1319)  评论(0编辑  收藏  举报