直接上代码
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 }
运行结果如下: