zoukankan      html  css  js  c++  java
  • 在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;
    }

    运行结果如下:

  • 相关阅读:
    Selenium 疑问之一:WebDriver 获得弹出窗口(转)
    Selenium 疑问之三:Selenium2.0 对于Wrapped元素的click()不起作用怎么办?
    [转]网站性能工具Yslow的使用方法
    Hudson + Ant + SVN + Tomcat配置详解
    Selenium 疑问之二:如何使页面滚动条移动到指定元素element的位置处?
    【转】组合测试法中的全对偶测试法
    Ant 之property 总结
    [转载]使用Selenium2测试含有iframe的Ajax网页
    Nginx反向代理WebSocket链接失败问题
    WebSocket语法糖
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3933423.html
Copyright © 2011-2022 走看看