首页 > 代码库 > 在String中添加移动构造函数和移动赋值运算符

在String中添加移动构造函数和移动赋值运算符

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;}

运行结果如下:

在String中添加移动构造函数和移动赋值运算符