13.44 编写标准库string类的简化版本,命名String。你的类应该至少有一个默认构造函数和一个接受C风格字符串指针参数的构造函数。使用allocator为你的String类分配所需内存。
13.47 添加拷贝构造函数和拷贝赋值运算符,并添加打印语句,则每次函数执行时打印一条信息。
13.48 定义一个vector<String>并在其上多次调用push_back。运行程序,观察String被拷贝了多少次。
#include<iostream> #include<string> #include<memory> #include<utility> #include<cstring> #include<vector> using namespace std; class String { public: String()=default; String(char *c); String(const String&); String& operator=(const String&); string* begin() const { return elements;} string* end() const { return first_free;} 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; } 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; }
运行结果: