• 在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<<"
    ";
    
        std::vector<String> v;
        String s;
        for (unsigned i = 0; i != 4; ++i)
        {
            std::cout << v.capacity() << "
    ";
            v.push_back(s);
        }
        return 0;
    }

    运行结果如下:

  • 相关阅读:
    liunx centos下tomcat启动 Cannot find ./catalina.sh
    ls -bash: ls: command not found
    Linux CentOS下安装JDK1.7
    查看Linux Centos 系统信息 内核 CPU 系统版本 磁盘 分区 网络配置 进程 命令
    PHP自动捕捉监控致命错误(500错误) error_get_last() 获取最后一次发生错误信息 register_shutdown_function()在脚本停止执行时注册一个回调函数
    CI CodeIgniter 添加公共函数 全局函数 自定义函数
    express框架封装前戏
    怎奈风云多变换,骚完一波还一波,记PHP mongodb驱动的2019年11月用法
    linux ps sample
    利用python pika库实现rabbitmq客户端
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3933423.html
Copyright © 2020-2023  润新知