c++的右值引用具體用法

在c++11中,支持右值引用,右值引用的用處之一是移動語義,對象的資源所有權發生轉移,在c++11之前,移動語義的缺失是c++飽受詬病的問題之一.

什麼是左值?什麼是右值?

凡有名者,皆爲左值.左值對應變量的存儲位置,右值對應變量的值本身,右值可以被賦值給左值,或者綁定到引用.

右值引用的優點?

類的右值是一個臨時對象,如果沒有被綁定到引用,在表達式結束時候,就會廢棄,在右值被廢棄之前,移走資源進行廢物利用.

被移走資源的右值在廢棄時已經成爲空殼,析構的開銷降低.

爲臨時變量續命,也就是爲右值續命,右值在表達式結束後就消亡了,如果想繼續使用右值,就會使用昂貴的拷貝構造函數

如果能夠直接使用臨時對象已經申請的資源,既能節省資源,又能節省資源申請和釋放的時間

看一個具體的例子:

#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class TestString
{
        private:
                char *data_;
                size_t len_;
                void _init_data(const char *p)
                {
                        data_ = new char[len_ + 1];
                        memcpy(data_, p, len_);
                        data_[len_] = '\0';
                }
        public:
                TestString()
                {
                        data_ = NULL;
                        len_ = 0;
                }

                TestString(const char *p)
                {
                        len_ = strlen(p);
                        _init_data(p);
                }

                TestString(const TestString &str)
                {
                        len_ = str.len_;
                        _init_data(str.data_);
                        std::cout << "Copy Structor is called! source:" << str.data_ << std::endl;
                }

                TestString& operator=(const TestString &str)
                {
                        if(this != &str)
                        {
                                len_ = str.len_;
                                _init_data(str.data_);
                        }
                        std::cout << "Copy Assignment is called! source:" << str.data_ << std::endl;
                        return *this;
                }

                //TestString(TestString &&str)
                //{
                //        std::cout << "Move Constructor is called! source:" << str.data_ << std::endl;
                //        len_ = str.len_;
                //        data_ = str.data_;
                //        str.len_ = 0;
                //        str.data_ = NULL;
                //}

                //TestString& operator=(TestString &&str)
                //{
                //        std::cout << "Move Assignment is called! source:" << str.data_ << std::endl;
                //        if(this != &str)
                //        {
                //                len_ = str.len_;
                //                data_ = str.data_;
                //                str.len_ = 0;
                //                str.data_ = NULL;
                //        }
                //        return *this;
                //}
                virtual ~TestString()
                {
                        if(data_)
                        {
                                delete []data_;
                                data_ = NULL;
                        }
                }
};

int main(int argc, char *argv[])
{

        TestString a;
        a = TestString("Hello ");
        std::vector<TestString> vec;
        vec.push_back(TestString(" Wrold"));
        return 0;
}

說明兩點:

(1)左值引用符號&,右值引用符號&&,右值引用符號只有在c++11中才被支持;

(2)程序中的註釋部分,包含右值引用拷貝構造函數和右值引用賦值構造函數,取消註釋前後程序的運行結果不一致,可以體會一下右值引用的含義,以及移動語義的優點:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章