真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++之移動(dòng)構(gòu)造函數(shù)-創(chuàng)新互聯(lián)

1、左值和右值

C++( 包括 C) 中所有的表達(dá)式和變量要么是左值,要么是右值。

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比瀘溪網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式瀘溪網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋瀘溪地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。
  1. 通俗的左值的定義就是非臨時(shí)對象,那些可以在多條語句中使用的對象,表達(dá)式結(jié)束后依然存在的持久化對象,所有的具名變量或者對象都是左值。
  2. 右值是指臨時(shí)的對象,它們只在當(dāng)前的語句中有效,他就像是代表了一個(gè)由編譯器創(chuàng)建的臨時(shí)內(nèi)存位置,在訪問它之后,該內(nèi)存就會(huì)被回收,該值也不能被訪問了。

具體代碼如下 :

int i = 0;           // i是左值, 0是右值,i在當(dāng)前表達(dá)式結(jié)束之后,依然可以被使用,被引用,而0不行,它是臨時(shí)值,當(dāng)前表達(dá)式結(jié)束之后,此表達(dá)式中的0值就不存在了
 
class A {
  public:
    int a;
};
 A getTemp()
{
    return A();
}
A a = getTemp();      // a是左值  getTemp()的返回值是右值(臨時(shí)變量)
 
((i>0) ? i : j) = 1;   //右值不只是存在在表達(dá)式的右邊,在此表達(dá)式中,0作為右值出現(xiàn)在表達(dá)式的左邊,并且將值賦值給i或者j。  
 
const int &a = 1;     //在 C++11 之前,右值是不能被引用的,大限度就是用常量引用綁定一個(gè)右值
 
T().set().get();      //在這種情況下,右值是可以被修改的,T 是一個(gè)類,set 是一個(gè)函數(shù)為 T 中的一個(gè)變量賦值,get 用來取出這個(gè)變量的值。在這句中,T() 生成一個(gè)臨時(shí)對象,就是右值,set() 修改了變量的值,也就修改了這個(gè)右值。
2、左值引用和右值引用

(1)左值引用就是最傳統(tǒng)的引用 &。
如下:

int a = 10;
int& refA = a; // refA是a的別名, 修改refA就是修改a, a是左值,左移是左值引用
int& b = 1; //編譯錯(cuò)誤! 1是右值,不能夠使用左值引用

(2)C++ Primer Plus 第6版18.1.9中說到,c++11中增加了右值引用,右值引用關(guān)聯(lián)到右值時(shí),右值被存儲(chǔ)到特定位置,右值引用指向該特定位置,也就是說,右值雖然無法獲取地址,但是右值引用是可以獲取地址的,該地址表示臨時(shí)對象的存儲(chǔ)位置。具體語法如下:

int&& a = 1; // &&是右值引用的符號,實(shí)質(zhì)上就是將不具名(匿名)變量取了個(gè)別名
int b = 1;
int && c = b; //編譯錯(cuò)誤! 不能將一個(gè)左值復(fù)制給一個(gè)右值引用

(3) 右值引用的三個(gè)特點(diǎn):
a、通過右值引用的聲明,右值又“重獲新生”,其生命周期與右值引用類型變量的生命周期一樣長,只要該變量還活著,該右值臨時(shí)量將會(huì)一直存活下去。

class A {
  public:
    int a;
};
A getTemp()
{
    return A();
}
A && a = getTemp();   //getTemp()的返回值是右值(臨時(shí)變量)getTemp()返回的右值本來在表達(dá)式語句結(jié)束后,其生命也就該終結(jié)了(因?yàn)槭桥R時(shí)變量),
                      //而通過右值引用,該右值又重獲新生,其生命期將與右值引用類型變量a的生命期一樣,只要a還活著,該右值臨時(shí)變量將會(huì)一直存活下去。

b、右值引用獨(dú)立于左值和右值。意思是右值引用類型的變量可能是左值也可能是右值。
從下面的代碼中可以看到,T&&表示的值類型不確定,可能是左值又可能是右值,這就是右值引用的一個(gè)特點(diǎn)。

templatevoid f(T&& t){}
 
f(10); //t是右值
 
int x = 10;
f(x); //t是左值

c、T&& t在發(fā)生自動(dòng)類型推斷的時(shí)候,它是未定的引用類型(universal references),如果被一個(gè)左值初始化,它就是一個(gè)左值;如果它被一個(gè)右值初始化,它就是一個(gè)右值,它是左值還是右值取決于它的初始化。

templatevoid f(T&& t){}
f(10); //t是右值   //這里發(fā)生自動(dòng)類型推斷
 
int x = 10;
f(x); //t是左值    //發(fā)生自動(dòng)類型推斷
 
templateclass Test {
    Test(Test&& rhs); //這里不會(huì)發(fā)生類型推斷,因?yàn)橐呀?jīng)是確定的Tset &&類型的
};
3、const左值引用

從上面的例子可以看到,
左值引用只能綁定左值,右值引用只能綁定右值,如果綁定的不對,編譯就會(huì)失敗。但是,const左值引用卻是個(gè)奇葩,它可以算是一個(gè)“萬能”的引用類型,它可以綁定非常量左值、常量左值、右值,而且在綁定右值的時(shí)候,常量左值引用還可以像右值引用一樣將右值的生命期延長,缺點(diǎn)是,只能讀不能改。

const int & a = 1; //常量左值引用綁定 右值, 不會(huì)報(bào)錯(cuò)
 
class A {
  public:
    int a;
};
A getTemp()
{
    return A();
}
const A & a = getTemp();   //不會(huì)報(bào)錯(cuò) 而 A& a 會(huì)報(bào)錯(cuò)

總結(jié)如下(其中T是一個(gè)類型):
左值引用, 使用 T&, 只能綁定左值
右值引用, 使用 T&&, 只能綁定右值
常量左值, 使用 const T&, 既可以綁定左值又可以綁定右值
已命名的右值引用,編譯器會(huì)認(rèn)為是個(gè)左值

4、移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值函數(shù)

首先,移動(dòng)構(gòu)造函數(shù)是一個(gè)構(gòu)造函數(shù),他是用來構(gòu)造一個(gè)對象的,和拷貝構(gòu)造函數(shù)、構(gòu)造函數(shù)等價(jià)。但與默認(rèn)構(gòu)造函數(shù)不同,編譯器不提供默認(rèn)移動(dòng)構(gòu)造函數(shù)。移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值函數(shù)所執(zhí)行的是同樣的操作,只不過情況不一樣,一種是直接構(gòu)造一個(gè)對象,另一種是利用“=”運(yùn)算符把一個(gè)對象賦值給另一個(gè)對象的時(shí)候。
移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值函數(shù)與拷貝構(gòu)造函數(shù)所執(zhí)行的作用的是一樣的,都是通過一個(gè)對象去構(gòu)造一個(gè)新對象。但有時(shí)候我們會(huì)遇到這樣一種情況,我們用對象a初始化對象b,后對象a我們就不在使用了,但是對象a掌握的內(nèi)存資源仍然存在(在析構(gòu)之前),既然拷貝構(gòu)造函數(shù),實(shí)際上就是把a(bǔ)對象的內(nèi)容復(fù)制一份到b中,那么為什么我們不能直接使用a對象掌握的內(nèi)存空間?這樣就避免了新的空間的分配,大大降低了構(gòu)造的成本。這就是移動(dòng)構(gòu)造函數(shù)設(shè)計(jì)的初衷。
總的來說,就是類中有指針類型的成員變量時(shí),當(dāng)遇到對象構(gòu)造對象時(shí),需要使用拷貝構(gòu)造函數(shù)中的深拷貝的方式把該指針成員賦值,這種深拷貝的方法會(huì)重新在堆上分配成員指針分配內(nèi)存,當(dāng)出現(xiàn)多次上述對象a初始化對象b之后,對象a不在存在的情況是,程序就會(huì)在堆上分配多次內(nèi)存,大大降低程序運(yùn)行效率,所以移動(dòng)構(gòu)造函數(shù)就將即將放棄的對象的內(nèi)存空間直接給新對象使用,就能避免許多臨時(shí)對象的創(chuàng)建,也能避免程序多次在堆上申請空間,從而大大的提高了執(zhí)行效率。他的原型如下:

A & operator=(A &&); //右值引用
  //正確的移動(dòng)構(gòu)造函數(shù)的寫法
  A(A && a):p(a.p)
  {
        std::cout<<"move c"<

對于移動(dòng)構(gòu)造函數(shù),需要以下幾點(diǎn)需要注意:
參數(shù)(右值)的符號必須是右值引用符號,即“&&”,因?yàn)橛抑凳羌磳⑽鰳?gòu)的對象,將它的內(nèi)存空間變廢為用,可以提高效率。
參數(shù)(右值)不可以是常量,因?yàn)槲覀冃枰薷挠抑怠?br />參數(shù)(右值)的資源鏈接和標(biāo)記必須修改。否則,右值的析構(gòu)函數(shù)就會(huì)釋放資源。轉(zhuǎn)移到新對象的資源也就無效了。
移動(dòng)構(gòu)造函數(shù)的原理如下圖:
在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:C++之移動(dòng)構(gòu)造函數(shù)-創(chuàng)新互聯(lián)
新聞來源:http://weahome.cn/article/coscji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部