首页 > 代码库 > 【足迹C++primer】47、Moving Objects(1)

【足迹C++primer】47、Moving Objects(1)

Moving Objects(1)

* 功能:Moving Objects
* 时间:2014年7月17日08:46:45
* 作者:cutter_point
*/

#include<iostream>
#include<string>
#include<memory>
#include<utility>
#include<vector>
#include<algorithm>
#include<set>
#include<map>


using namespace std;
/**************************************
Rvalue References
**************************************/
void fun1()
{
    int i=42;
    int &r=i;   //引用,r引用了i
//    int &&rr=i; //错误,不能右值引用一个值
//    int &r2=i*42;   //错误,i*42是一个右值
    const int &r3=i*42; //ok,我们可愿意绑定一个右值在const上
    int &&rr2=i*42;     //吧rr2绑定到结果上
    //个人理解就是&单个是引用别名,而&&也是引用但是是const结果
}
/**************************************
Lvalues Persist; Rvalues Are Ephemeral
左值长久,右值一瞬
**************************************/
/*
Rvalue references refer to objects that are about to be destroyed. Hence, we
can “steal” state from an object bound to an rvalue reference.
*/

/**************************************
Variables Are Lvalues
**************************************/
void fun2()
{
    int &&rr1=42;   //正确,这&&rr1是右值,不能是变化的
//    int &&rr2=rr1;  //错误由于rr1是一个左值,不能引用为右值
}

/*
A variable is an lvalue; we cannot directly bind an rvalue reference to a
variable even if that variable was defined as an rvalue reference type
*/

/**************************************
The Library move Function
**************************************/
void fun3()
{
    int &&rr1=42;   //正确,这&&rr1是右值,不能是变化的
    int &&rr2=std::move(rr1);  //用move吧这rr1转换成左值
}
/*
We can destroy a moved-from object and can assign a new value to it, but
we cannot use the value of a moved-from object.
Warning:
Code that uses move should use std::move, not move. Doing so avoids
potential name collisions.
*/

/**************************************
13.6.2. Move Constructor and Move Assignment
**************************************/

/**
Move Operations, Library Containers, and Exceptions
*/
class StrVec
{
public:
    StrVec():elements(nullptr), first_free(nullptr), cap(nullptr){}
    StrVec(const StrVec&);
    StrVec(StrVec&&) noexcept;
    StrVec & operator=(const StrVec&);
    StrVec & operator=(StrVec&&) noexcept;
    ~StrVec();

    string* begin() const {return elements;}            //起始指针
    string* end() const {return first_free;}            //第一个为空的元素
    void push_back(const string&);  //拷贝元素进入队列
    size_t size() const {return first_free-elements;}   //队列存放元素个数
    size_t capacity() const {return cap-elements;}      //队列存储空间大小

private:
    allocator<string> alloc;
    string* elements;
    string* first_free;
    string* cap;
    pair<string*, string*> alloc_n_copy(const string*, const string*);
    void free();
    void reallocate();  //重新分配空间并且把原来的元素移动到新空间上
    void chk_n_alloc()
    {
        if(size() == capacity())        //判断数据长度是否已经达到分配空间的上限
            reallocate();       //如果是,那么就重新分配空间
    }

};

/**************************************
Move Iterators
**************************************/
void StrVec::reallocate()
{
    //分配新空间
    auto newcapacity=size() ? 2*size() : 1;
    auto first=alloc.allocate(newcapacity);

    auto last=uninitialized_copy(make_move_iterator(begin()), make_move_iterator(end()), first);
    free();
    elements=first;
    first_free=last;
    cap=elements+newcapacity;
}

inline
StrVec::~StrVec()
{
    free();
}

inline
pair<string*, string*>
StrVec::alloc_n_copy(const string* b, const  string* e) //开始和结尾指针
{
    //要拷贝对象要求的空间大小
    auto data=http://www.mamicode.com/alloc.allocate(e-b);>

PS:代码全在,里面各种注释,我一后还是这样写吧,除了一些特殊的感悟自己写出来,然后大部分大家直接在代码中学习,这样避免了,看那些文字的烦躁,和那些看文字的无聊!!!
今天早上出去溜达一圈,回来早餐吃泡面,尼玛,我真是服了,第一次早上吃泡面,然后把面什么的放碗里,最后把调料又放回了袋子里,我的天!!!