欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

c++的左值(lvalue),右值(rvalue),移動語義(move),完美轉(zhuǎn)發(fā)(forward)

c++的左值(lvalue),右值(rvalue),移動語義(move),完美轉(zhuǎn)發(fā)(forward)

c++的左值,右值 精辟總結(jié)

成都創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的萬秀網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

當(dāng)一個對象被用作右值的時候,使用的是對象的值(內(nèi)容);當(dāng)對象被用作左值的時候,用的是對象的身份(在內(nèi)存中的位置)左值右值,完美轉(zhuǎn)發(fā)參考文檔。

左值持久,右值短暫;move:顯示地將一個左值轉(zhuǎn)換為對應(yīng)右值的引用類型,還可以獲取綁定到左值上的右值引用,int&& rr3 = std::move(rrl); 使用move就意味著除了對rrl賦值或銷毀它外,我們不再使用它。

std::forward()與std::move()相區(qū)別的是,move()會無條件的將一個參數(shù)轉(zhuǎn)換成右值,而forward()則會保留參數(shù)的左右值類型,可以使用std::forward實現(xiàn)完美轉(zhuǎn)發(fā)

移動語義解決了無用拷貝的問題:移動構(gòu)造函數(shù);

右值引用:函數(shù)的返回值。

int& 左值引用

int&& 右值引用

c++中無用拷貝的情況

/*類里面 沒有移動構(gòu)造函數(shù)
這樣就會使用 copy construct function,會導(dǎo)致大量無用的 memory copy。
*/
class Test {  
public:
    string desc; 
    int * arr{nullptr};
    Test():arr(new int[5000]{1,2,3,4}) { 
        cout << "default constructor" << endl;
    }
    Test(const Test & t) {
        cout << "copy constructor" << endl;
        if (arr == nullptr) arr = new int[5000];
        copy(t.arr,t.arr+5000, arr);
    }
    ~Test(){
        cout << "destructor " << desc << endl;
        delete [] arr;
    }
};

Test createTest() {
    return Test();
}

int main(){

    Test reusable;
    reusable.desc = "reusable";
    Test duplicated(reusable);
    duplicated.desc = "duplicated";

    Test t(createTest());
    t.desc = "t";

    cout<<"end"<<endl;
}

運行結(jié)果

default constructor
copy constructor
default constructor
end
destructor t
destructor duplicated
destructor reusable

使用移動語義避免無用的拷貝

/*使用移動 construct function,避免無用的memory copy。
*/

class Test {   
    public:
    string desc;
    int * arr{nullptr};
    Test():arr(new int[5000]{1,2,3,4}) { 
        cout << "__default constructor" << endl;
    }
    Test(const Test & t) {
        cout << "__copy constructor" << endl;
        if (arr == nullptr) arr = new int[5000]; //在這里要將 t.arr 置為空,因為經(jīng)過move之后,我們認為不在使用這個值了,避免在新的對象中把指針釋放后,原來的對象中存在野指針的現(xiàn)象
        copy(t.arr,t.arr+5000, arr);
    }
    Test(Test && t): arr(t.arr) {
        cout << "__move constructor" << endl;
        t.arr = nullptr;
    }
    ~Test(){
        cout << "..destructor " << desc << endl;
        delete [] arr;
    }
};

Test createTest(string str) {
    Test rt;
    rt.desc = str;
    cout<<"createTest:"<<&rt<<endl;
    return rt;
}

void main(){
    Test reusable;
    reusable.desc = "reusable";
    cout<<"reusable.arr "<<reusable.arr<<endl;
    
    Test duplicated(std::move(reusable));
    duplicated.desc = "duplicated";
    cout<<"reusable.arr "<<reusable.arr<<endl;
    cout<<"duplicated.arr "<<duplicated.arr<<endl;

    cout<<"rvalue--"<<endl;
    Test&& rt1 = createTest("rval");      //使用右值引用接收
    cout<<"rt1.arr "<<rt1.arr<<endl;
    
    cout<<"no rvalue--"<<endl;
    Test rt2 = createTest("normalVal");      //不使用右值引用接收,可以看到這里比使用右值引用接收 多了一次構(gòu)造和析構(gòu)(createTest中的臨時對象)
    cout<<"createTest:"<<&rt2<<endl;        //尷尬,其實這里編譯器已經(jīng)做了優(yōu)化了,可以看到第地址一樣
    cout<<"rt2.arr "<<rt2.arr<<endl;

    cout<<"end"<<endl;
}

輸出結(jié)果

__default constructor
reusable.arr 0xb946e70
__move constructor
reusable.arr 0
duplicated.arr 0xb946e70
rvalue--
__default constructor
createTest:0x7ffd092ea390
rt1.arr 0xb94c0b0
no rvalue--
__default constructor
createTest:0x7ffd092ea3c0
createTest:0x7ffd092ea3c0
rt2.arr 0xb950ee0
end
..destructor normalVal
..destructor rval
..destructor duplicated
..destructor reusable

左值引用右值引用

//左值引用和右值引用
void foo(const int & i) { cout << "const int & " << i << endl; }
void foo(int & i) {  cout << "int & " << i << endl; }
void foo(int && i) { cout << "int && " << i << endl; }
void foo(const int && i) { cout << "const int && " << i << endl; }
void main(){
    int i = 2;
    foo(i);
    foo(2);
    foo([]()->const int && {return 2;}());
}

完美轉(zhuǎn)發(fā)

/*在main當(dāng)中調(diào)用relay,Test的臨時對象作為一個右值傳入relay,在relay當(dāng)中又被轉(zhuǎn)發(fā)給了func,那這時候轉(zhuǎn)發(fā)
給func的參數(shù)t也應(yīng)當(dāng)是一個右值。也就是說,我們希望:當(dāng)relay的參數(shù)是右值的時候,func的參數(shù)也是右值;當(dāng)
relay的參數(shù)是左值的時候,func的參數(shù)也是左值。
*/
class Test {   
    public:
    int * arr{nullptr};
    Test():arr(new int[5000]{1,2,3,4}) { 
        cout << "default constructor" << endl;
    }
    Test(const Test & t) {
        cout << "copy constructor" << endl;
        if (arr == nullptr) arr = new int[5000];
        copy(t.arr,t.arr+5000, arr);
    }
    Test(Test && t): arr(t.arr) {
        cout << "move constructor" << endl;
        t.arr = nullptr;
    }
    ~Test(){
        cout << "destructor" << endl;
        delete [] arr;
    }
};

template <typename T>
void func(T t) {
    cout << "in func" << endl;
}

template <typename T>
void relay(T&& t) {
    cout << "in relay" << endl;
    func(t);
}
//完美轉(zhuǎn)發(fā)
template <typename T>
void relay1(T&& t) {
    cout << "in relay " << endl;
    func(std::forward<T>(t));
}

void main() {
    // relay(Test());
    // cout<<"end"<<endl;

    relay1(Test());
    cout<<"end"<<endl;

}

更多編程資料見公眾號 xutopia77

網(wǎng)站題目:c++的左值(lvalue),右值(rvalue),移動語義(move),完美轉(zhuǎn)發(fā)(forward)
瀏覽路徑:http://chinadenli.net/article14/dsogoge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、面包屑導(dǎo)航網(wǎng)站制作、網(wǎng)站設(shè)計、網(wǎng)站設(shè)計公司建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司