zoukankan      html  css  js  c++  java
  • 【足迹C++primer】47、Moving Objects(2)

    版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/cutter_point/article/details/37954805
    Moving Objects(2)

    Rvalue References and Member Functions

    StrVec.h

    #ifndef STRVEC_H
    #define STRVEC_H
    
    #include <iostream>
    #include <memory>
    #include <utility>
    
    // simplified implementation of the memory allocation strategy for a vector-like class
    class StrVec {
    public:
    	// copy control members
        StrVec():
    	  elements(0), first_free(0), cap(0) { }
    
    	StrVec(const StrVec&);            // copy constructor
    	StrVec &operator=(const StrVec&); // copy assignment
    
    	~StrVec();                            // destructor
    
    	// additional constructor
    	StrVec(const std::string*, const std::string*);
    
        void push_back(const std::string&);  // copy the element
        void push_back(std::string&&);       //move the element
    
    	// add elements
        size_t size() const { return first_free - elements; }
        size_t capacity() const { return cap - elements; }
    
    	// iterator interface
    	std::string *begin() const { return elements; }
    	std::string *end() const { return first_free; }
    
    	// operator functions covered in chapter 14
    	std::string& operator[](std::size_t n)
    		{ return elements[n]; }
    
    	const std::string& operator[](std::size_t n) const
    		{ return elements[n]; }
    
    private:
        static std::allocator<std::string> alloc; // allocates the elements
    
    	// utility functions:
    	//  used by members that add elements to the StrVec
    	void chk_n_alloc()
    		{ if (size() == capacity()) reallocate(); }
        // used by the copy constructor, assignment operator, and destructor
    	std::pair<std::string*, std::string*> alloc_n_copy
    	    (const std::string*, const std::string*);
    	void free();             // destroy the elements and free the space
        void reallocate();       // get more space and copy the existing elements
        std::string *elements;   // pointer to the first element in the array
        std::string *first_free; // pointer to the first free element in the array
        std::string *cap;        // pointer to one past the end of the array
    };
    
    #include <algorithm>
    
    inline
    StrVec::~StrVec() { free(); }
    
    inline
    std::pair<std::string*, std::string*>
    StrVec::alloc_n_copy(const std::string *b, const std::string *e)
    {
    	// allocate space to hold as many elements as are in the range
    	std::string *data = alloc.allocate(e - b);
    
    	// initialize and return a pair constructed from data and
    	// the value returned by uninitialized_copy
    	return std::make_pair(data, uninitialized_copy(b, e, data));
    }
    
    inline
    StrVec::StrVec(const StrVec &s)
    {
    	// call alloc_n_copy to allocate exactly as many elements as in s
    	std::pair<std::string*, std::string*> newdata =
    							alloc_n_copy(s.begin(), s.end());
    	elements = newdata.first;
    	first_free = cap = newdata.second;
    }
    
    inline
    void StrVec::free()
    {
        // may not pass deallocate a 0 pointer; if elements is 0, there's no work to do
    	if (elements) {
        	// destroy the old elements in reverse order
    		for (std::string *p = first_free; p != elements; /* empty */)
    			alloc.destroy(--p);
    		alloc.deallocate(elements, cap - elements);
    	}
    }
    
    inline
    StrVec &StrVec::operator=(const StrVec &rhs)
    {
    	// call alloc_n_copy to allocate exactly as many elements as in rhs
    	std::pair<std::string*, std::string*> data =
    							alloc_n_copy(rhs.begin(), rhs.end());
    	free();
    	elements = data.first;
    	first_free = cap = data.second;
    	return *this;
    }
    
    inline
    void StrVec::reallocate()
    {
        // we'll allocate space for twice as many elements as the current size
        size_t newcapacity = size() ? 2 * size() : 1;
    
    	// allocate new memory
    	std::string *newdata = alloc.allocate(newcapacity);
    
    	// copy the data from the old memory to the new
    	std::string *dest = newdata;  // points to the next free position in the new array
        std::string *elem = elements; // points to the next element in the old array
    	for (size_t i = 0; i != size(); ++i)
    		alloc.construct(dest++, *elem++);
    
    	free();  // free the old space once we've moved the elements
    
        // update our data structure to point to the new elements
        elements = newdata;
        first_free = dest;
        cap = elements + newcapacity;
    }
    
    inline
    StrVec::StrVec(const std::string *b, const std::string *e)
    {
    	// call alloc_n_copy to allocate exactly as many elements as in il
    	std::pair<std::string*, std::string*> newdata = alloc_n_copy(b, e);
    	elements = newdata.first;
    	first_free = cap = newdata.second;
    }
    
    #endif
    

    StrVec.cc


    #include "StrVec.h"
    
    #include <string>
    #include <utility>
    
    // errata fixed in second printing -- 
    // StrVec's allocator should be a static member not an ordinary member
    
    // definition for static data member
    std::allocator<std::string> StrVec::alloc;  
    
    // all other StrVec members are inline and defined inside StrVec.h
    

    inline
    void StrVec::push_back(const string& s)
    {
        chk_n_alloc(); // ensure that there is room for another element
        // construct a copy of s in the element to which first_free points
        alloc.construct(first_free++, s);
    }
    
    inline
    void StrVec::push_back(string&& s)
    {
        chk_n_alloc();
        alloc.construct(first_free++, std::move(s));
    }
    
    void fun1()
    {
        StrVec vec;
        string s="my name is cutter_point!";
        vec.push_back(s);   //调用const string&这个
        vec.push_back("China!");    //调用string&&
    }
    

    class Foo
    {
    public:
        Foo()=default;
        Foo(const Foo&);    //copy构造函数
    
        Foo &operator=(const Foo&) &;   //返回一个左值&&表示返回右值
    //    Foo someMem() & const;          //错误,const应放第一位
        Foo anotherMem() const &;       //正确
    };
    
    Foo &Foo::operator=(const Foo &rhs) &
    {
        return *this;
    }
    
    Foo::Foo(const Foo &f)
    {
    
    }
    
    void fun2()
    {
        Foo &retFoo();  //返回一个引用,是一个左值
        Foo retVal();      //返回一个值,右值调用
        Foo i, j;       //i,j是左值
        i=j;            //i是左值
    //    retFoo()=j;     //OK这个返回的是一个左值
    //    retVal()=j;     //错误。retVal是一个右值
    }
    

    Overloading and Reference Functions

    class Foo
    {
    public:
        Foo()=default;
    //    Foo(const Foo&);    //copy构造函数
    //    Foo(Foo&&);
    
        Foo &operator=(const Foo&) &;   //返回一个左值&&表示返回右值
    //    Foo someMem() & const;          //错误。const应放第一位
        Foo anotherMem() const &;       //正确
        Foo sorted() &&;        //返回右值
        Foo sorted() const &;   //返回左值
    private:
        vector<int> data;
    };
    
    Foo Foo::sorted() &&
    {
        sort(data.begin(), data.end());
        return *this;
    }
    
    Foo Foo::sorted() const &
    {
        Foo ret(*this);
        sort(ret.data.begin(), ret.data.end());
        return ret;
    }
    

    int main()
    {
        string s1="a value", s2="this is a pig.";
        auto n=(s1+s2).find('e');
        cout<<n<<endl;
        return 0;
    }
    

    PS:如今的感觉是非常不爽。不知道学这玩意什么时候才干去找工作。不知道去那好,还是耐心点。耐着性子,仅仅要默默地向自己的目标前进就好。未来有我的机遇等着我,我如今要做的就是在机遇来的时候我能够狠狠的抓住!

    !!

    以免懊悔一生



查看全文
  • 相关阅读:
    1069.查找学生信息
    1023.Excel排序
    1061.成绩排序
    bzoj 1113
    bzoj 1112 treap树
    bzoj 1225 dfs + 一点点数论
    bzoj 1224
    UESTC
    HDU 3530 单调队列
    bzoj 1233
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10878325.html
  • Copyright © 2011-2022 走看看