美文网首页c++
C++11:右值引用和转移赋值

C++11:右值引用和转移赋值

作者: 行走的代码 | 来源:发表于2020-06-20 22:11 被阅读0次

    1.首先认识左值和右值的定义:

    左值:表达式可以引用到一个对象,并且这个对象是一块内存空间并可以检测和存储,这个表示即是左值。

    右值:直接引用了一个存储在内存地址中的数据。

    右值最大限度只能被一个常量引用:

    1
    const int &a = 1;
    规则:临时变量是右值,且可以改变:

    1
    T().set().get()
    T为临时变量,set()设置新值,get()获取更改后的值。

    2.首先写一个MyString类:

    #include<vector>
    class MyString
    {
    private:
        int _len;
        char* _data;
        void init_data(const char* str)
        {
            _data = new char[_len+1];
            memcpy(_data,str,_len);
            _data[_len] = '\0';
        }
    public:
        MyString()
        {
            _len = 0;
            _data = NULL;
        }
        MyString(const char* str)
        {
            _len = strlen(str);
            init_data(str);
        }
        MyString(const MyString& rhs)
        {
            _len = rhs._len;
            init_data(rhs._data);
        }
        MyString& operator=(MyString& rhs)
        {
            if(this != &rhs)
            {
                _len = rhs._len;
                init_data(rhs._data);
                //MyString(rhs);
            }
            return *this;
        }
        virtual ~MyString()
        {
            if(_data) free(_data);
        }
    };
    int main()
    {
        Mystring a;
        a = MyString("Hello");
        std::vector<MyString> vec;
        vec.push_back(MyString("World"));
    }
    

    左值和右值引用符号区别:

    void print_value(int& a)
    {
      std::cout << "LValue" << endl;
    }
    void print_value(int&& a)
    {
      std::cout << "RValue" << endl;
    }
    

    右值引用实际是用来支持转移赋值和转移构造:

    MyString(MyString&& rhs)        //不包含const
    {
        _len = rhs._len;
        _data = rhs._data;
        rhs._len = 0;
        rhs._data = NULL;
    }
    MyString& operator(MyString&& rhs)  //不包含 const
    {
        if(this != &rhs)
        {
            _len = rhs._len;
            _data = rhs._data;
            rhs._len = 0;
            rhs._data = NULL;
        }
        return *this;
    }
    

    转移构造和赋值的好处是:节省了资源,提高了程序效率。

    std::move是标准库提供的将一个命名对象转换为一个临时对象(右值)来支持转移构造和赋值:

    template <class T> void swap(T& a, T& b)
    {
        T c(std::move(a));
        a=std::move(b);
        b=std::move(c);
    }
    template <class T, size_t N> void swap(T (&a)[N], T(&b)[N])
    {
        for(size_t i = 0; i<N; ++i) swap(a[i], b[i]);
    }
    

    这样提高了swap效率。

    未显式定义转移构造函数和转移赋值函数,会使用默认的。但有几种情况需要显式定义:

    1. 成员中含有裸指针,用默认的存在释放问题;
    2. 自定义了构造函数和赋值函数,那么需要显式定义move的方法;
    3. 显式定义析构函数,需要显式定义move方法;


      v2-c05999fd24c153670011c7eb161a7d8a_720w.jpg

    相关文章

      网友评论

        本文标题:C++11:右值引用和转移赋值

        本文链接:https://www.haomeiwen.com/subject/bkfnxktx.html