标签:exce ack ini line 答案 move 第一个 bsp algo
练习13.49 13.50
1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <memory> 5 #include <algorithm> 6 #include <vector> 7 8 using namespace std; 9 10 class String { 11 friend ostream &print(ostream &os, String &s); 12 public: 13 String(): element(nullptr), first_free(nullptr) {} 14 String(char *); 15 size_t size() const{ return first_free - element; } 16 String(const String&); 17 String& operator=(const String&); 18 String(String&&) noexcept; 19 String& operator=(String&&) noexcept; 20 ~String() { free(); } 21 private: 22 static allocator<char> alloc; 23 pair<char *, char *> alloc_n_copy(const char*, const char *); 24 void free(); 25 char *element; 26 char *first_free; 27 }; 28 allocator<char> String::alloc; 29 ostream &print(ostream &os, String &s); 30 31 int main() 32 { 33 vector<String> vec; 34 String s1("hello"); 35 String s2("world"); 36 String s3(s1); 37 String s4 = s2; 38 s3 = s1; 39 String s5 = std::move(s4); 40 vec.push_back(s1); 41 vec.push_back(s2); 42 vec.push_back(s3); 43 vec.push_back(s4); 44 vec.push_back(s5); 45 system("pause"); 46 return 0; 47 } 48 49 String::String(char *s) 50 { 51 int i = 0; 52 while (s[i] != ‘\0‘) 53 i = i + 1; 54 auto newloc = alloc.allocate(i); 55 auto dest = newloc; 56 for (auto count = 0; count != i;++count) 57 alloc.construct(dest++, s[count]); 58 element = newloc; 59 first_free = dest; 60 cout << "普通构造函数" << endl; 61 } 62 63 String::String(const String &s) 64 { 65 auto newdata = alloc_n_copy(s.element, s.first_free); 66 element = newdata.first; 67 first_free = newdata.second; 68 cout << "拷贝构造函数" << endl; 69 } 70 71 String & String::operator=(const String &rhs) 72 { 73 auto newdata = alloc_n_copy(rhs.element, rhs.first_free); 74 free(); 75 element = newdata.first; 76 first_free = newdata.second; 77 cout << "拷贝赋值运算符" << endl; 78 return *this; 79 // TODO: 在此处插入 return 语句 80 } 81 82 String::String(String &&s) noexcept : element(s.element), first_free(s.first_free) { s.element = s.first_free = nullptr; cout << "移动构造函数" << endl; } 83 84 String & String::operator=(String &&rhs) noexcept 85 { 86 if (this != &rhs) 87 { 88 element = rhs.element; 89 first_free = rhs.first_free; 90 rhs.element = rhs.first_free = nullptr; 91 } 92 cout << "移动赋值运算符" << endl; 93 return *this; 94 // TODO: 在此处插入 return 语句 95 } 96 97 pair<char*, char*> String::alloc_n_copy(const char *b, const char *e) 98 { 99 auto data = alloc.allocate(e - b); 100 return{ data,uninitialized_copy(b,e,data) }; 101 } 102 103 void String::free() 104 { 105 if (element) 106 { 107 for (auto p = first_free; p != element;) 108 alloc.destroy(--p); 109 alloc.deallocate(element,first_free - element); 110 } 111 } 112 113 ostream & print(ostream &os,String &s) 114 { 115 while (s.element != s.first_free) 116 { 117 os << *(s.element); 118 s.element++; 119 } 120 cout << endl; 121 return os; 122 // TODO: 在此处插入 return 语句 123 }
其他的移动构造函数和移动赋值运算符的写法类似,注意两点,一点是加上noexcept,还有一点事注意最后移动后原对象的安全释放。
练习13.51
我们可以拷贝或赋值一个将要销毁的unique_ptr,由于返回的值是一个临时对象,故他是一个右值绑定的引用,这里的拷贝和赋值是移动拷贝和移动赋值,他不是正常的拷贝,而是窃取资源。
练习13.52
两者的区别在于刚开始的将hp2赋值给rhs的过程,第一个调用拷贝构造函数,分配新内存,将hp2完全拷贝给rhs,这时就有两个一样的对象,而第二个式子是调用移动构造函数,他从hp2拷贝指针,而不会重新分配内存,再将原对象的指针置空,后面的操作都类似了。
练习13.53
注意拷贝赋值运算符由于是拷贝的原因移后源对象依然存在且不变,而移动赋值运算符移后源对象虽然在但是一般为了正确释放会置空;
1 HasPtr& operator=(HasPtr& rhs){ 2 delete ps; 3 swap(*this,rhs); 4 cout<<"HasPtr& operator=(HasPtr& rhs)"<<endl; 5 return *this; 6 } 7 HasPtr& operator=(HasPtr&& rhs){ 8 ps=std::move(rhs.ps); 9 i=std::move(rhs.i); 10 rhs.ps=nullptr;
1 #include <iostream> 2 #include <string> 3 #include <memory> 4 #include <vector> 5 #include <algorithm> 6 #include <numeric> 7 8 using namespace std; 9 10 class HasPtr { 11 friend ostream &print(ostream &os, HasPtr &h); 12 friend void swap(HasPtr &lhs, HasPtr &rhs); 13 friend bool operator<(HasPtr &lpt, HasPtr &rpt); 14 friend string & out(HasPtr &pt); 15 public: 16 HasPtr(const string &s = string()) : ps(new string(s)), i(0) {} 17 HasPtr(const HasPtr &ptr); 18 HasPtr &operator=(const HasPtr &pt); 19 HasPtr &operator=(HasPtr &&) noexcept; 20 ~HasPtr() { delete ps; } 21 22 private: 23 string *ps; 24 int i; 25 }; 26 27 ostream &print(ostream &os, HasPtr &h); 28 inline void swap(HasPtr &lhs, HasPtr &rhs); 29 bool operator<(HasPtr &lpt, HasPtr &rpt); 30 string & out(HasPtr &pt); 31 32 int main() 33 { 34 vector<HasPtr> svec; 35 string word; 36 while (cin >> word) 37 { 38 svec.push_back(*new HasPtr(word)); 39 } 40 sort(svec.begin(), svec.end()); 41 for (auto c : svec) 42 { 43 cout << out(c) << endl; 44 } 45 system("pause"); 46 return 0; 47 } 48 49 HasPtr::HasPtr(const HasPtr & ptr) : ps(new string(*(ptr.ps))), i(ptr.i) {} 50 51 HasPtr & HasPtr::operator=(const HasPtr & pt) 52 { 53 auto q = new string(*pt.ps); 54 delete ps; 55 ps = q; 56 i = pt.i; 57 cout << "0" << endl; 58 return *this; 59 } 60 61 HasPtr & HasPtr::operator=(HasPtr &&pt) noexcept 62 { 63 if (this != &pt) 64 { 65 delete ps; 66 ps = pt.ps; 67 i = pt.i; 68 pt.ps = nullptr; 69 } 70 cout << "1" << endl; 71 return *this; 72 // TODO: 在此处插入 return 语句 73 } 74 75 string & out(HasPtr & pt) 76 { 77 return *pt.ps; 78 } 79 80 bool operator<(HasPtr & lpt, HasPtr &rpt) 81 { 82 return (*lpt.ps).size() < (*rpt.ps).size(); 83 } 84 85 ostream & print(ostream & os, HasPtr & h) 86 { 87 os << *h.ps << h.i << endl; 88 return os; 89 } 90 91 inline void swap(HasPtr & lhs, HasPtr & rhs) 92 { 93 using std::swap; 94 swap(lhs.ps, rhs.ps); 95 cout << "ps already copy" << endl; 96 swap(lhs.i, rhs.i); 97 cout << "i already copy" << endl; 98 }
程序运行时没有调用拷贝赋值运算符,而是调用的移动赋值运算符,根据网上答案,应该和编译器有关。
11 cout<<"HasPtr& operator=(HasPtr&& rhs)"<<endl; 12 return *this; 13 }
练习13.54
标签:exce ack ini line 答案 move 第一个 bsp algo
原文地址:http://www.cnblogs.com/wuyinfenghappy/p/7481774.html