13.50 没有定义析构函数
#include<iostream> #include<string> #include<memory> #include<utility> #include<cstring> #include<vector> using namespace std; class String { public: String():elements(nullptr),first_free(nullptr) {} String(char *c); String(const String&); String& operator=(const String&); string* begin() const { return elements;} string* end() const { return first_free;} String(String &&); String& operator=(String &&); private: static allocator<string> alloc; string *elements; string *first_free; }; allocator<string> String::alloc; String::String(char *c) { size_t capacity=strlen(c); auto data=alloc.allocate(capacity); auto dest=data; string s; s.copy(c,strlen(c)); alloc.construct(dest++,s); elements=data; first_free=dest; } String::String(const String &s) { cout<<"copy construct"<<endl; auto capacity=s.end()-s.begin(); auto data=alloc.allocate(capacity); uninitialized_copy(s.begin(),s.end(),data); elements=data; first_free=data+capacity; } String& String::operator=(const String &s) { cout<<"copy = construct"<<endl; auto capacity=s.end()-s.begin(); auto data=alloc.allocate(capacity); uninitialized_copy(s.begin(),s.end(),data); if(elements) { auto begin=elements; auto end=first_free; while(begin!=end) alloc.destroy(begin++); alloc.deallocate(elements,first_free-elements); } elements=data; first_free=data+capacity; return *this; } String::String(String &&s):elements(s.elements),first_free(s.first_free) { cout<<"move construct"<<endl; s.elements=s.first_free=nullptr; } String& String::operator=(String &&s) { cout<<"move = construct"<<endl; if(this!=&s) { if(elements) { auto begin=elements; auto end=first_free; while(begin!=end) alloc.destroy(begin++); alloc.deallocate(elements,first_free-elements); } } elements=s.elements; first_free=s.first_free; s.elements=s.first_free=nullptr; return *this; } int main() { vector<String> vec; char ch[]="hello"; char ch1[]="world!"; cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; return 0; }
运行结果如下: 结果中出现移动构造函数是因为调用String构造函数返回的结果是右值
定义析构函数时:
#include<iostream> #include<string> #include<memory> #include<utility> #include<cstring> #include<vector> using namespace std; class String { public: String():elements(nullptr),first_free(nullptr){} String(char *c); String(const String&); String& operator=(const String&); string* begin() const { return elements;} string* end() const { return first_free;} //一定要定义析构函数,否则就算定义了移动构造函数还是不会调用,只会调用拷贝构造函数 ~String() { if(elements) { auto begin=elements; auto end=first_free; while(begin!=end) alloc.destroy(begin++); alloc.deallocate(elements,first_free-elements); } } String(String &&) noexcept; String& operator=(String &&) noexcept; private: static allocator<string> alloc; string *elements; string *first_free; }; allocator<string> String::alloc; String::String(char *c) { size_t capacity=strlen(c); auto data=alloc.allocate(capacity); auto dest=data; string s; s.copy(c,strlen(c)); alloc.construct(dest++,s); elements=data; first_free=dest; } String::String(const String &s) { cout<<"copy construct"<<endl; auto capacity=s.end()-s.begin(); auto data=alloc.allocate(capacity); uninitialized_copy(s.begin(),s.end(),data); elements=data; first_free=data+capacity; } String& String::operator=(const String &s) { cout<<"copy = construct"<<endl; auto capacity=s.end()-s.begin(); auto data=alloc.allocate(capacity); uninitialized_copy(s.begin(),s.end(),data); if(elements) { auto begin=elements; auto end=first_free; while(begin!=end) alloc.destroy(begin++); alloc.deallocate(elements,first_free-elements); } elements=data; first_free=data+capacity; return *this; } String::String(String &&s) noexcept :elements(s.elements),first_free(s.first_free) { cout<<"move construct"<<endl; s.elements=s.first_free=nullptr; } String& String::operator=(String &&s) noexcept { cout<<"move = construct"<<endl; if(this!=&s) { if(elements) { auto begin=elements; auto end=first_free; while(begin!=end) alloc.destroy(begin++); alloc.deallocate(elements,first_free-elements); } } elements=s.elements; first_free=s.first_free; s.elements=s.first_free=nullptr; return *this; } int main() { vector<String> vec; char ch[]="hello"; char ch1[]="world!"; cout<<vec.capacity()<<endl; cout<<endl; String ss(ch); vec.push_back(ss); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<endl; vec.push_back(String(ch1)); cout<<vec.capacity()<<endl; cout<<"\n"; std::vector<String> v; String s; for (unsigned i = 0; i != 4; ++i) { std::cout << v.capacity() << "\n"; v.push_back(s); } return 0; }
运行结果如下: