2014-12-21 104 views
0

我試圖寫的有效方法,以將圖像分配(一個QImage的 - Qt5.3)到我的類的成員變量:分配右值參照成員變量

void ImageView::setImage(QImage&& image){ 
    std::cout << &image << std::endl; 

    _image = image; 
    //_image = std::move(image); 

    std::cout << &_image << std::endl; 

    _imageAssigned = true; 
    updateResizedImage(); 
    update(); 
} 

有兩行代碼我可以使用,第一個是_image = image;,第二個是_image = std::move(image);。現在我認爲第一行應該是完全正確的,應該實際使用帶有右值引用的QImage的=運算符重載,因爲圖像已經是右值引用。然而,Visual Studio的工具提示顯示我使用了normal =操作符。如果我使用第二行代替,則工具提示顯示使用右值的重載。現在我的問題是爲什麼是這樣。第一行不夠?對已經是右值引用的變量進行調用似乎對我來說太過分了。

我試圖通過輸出指針來自己測試(如代碼中所見)。現在,無論我使用哪條線,指針都是不同的。這讓我感到困惑。看起來,我的代碼沒有按照我認爲的方式工作。誰能告訴我我做錯了什麼?

謝謝您的幫助

回答

4

與名稱的對象是一個左值。聲明爲QImage&&表示只有一個右值可以綁定到這個引用,但引用本身總是一個左值:它有一個名字。如果你想轉發一個實體的右值,你必須明確地使用std::move()。如果推導出右值(即,使用T&&形式的推導模板參數,其中T是模板參數),則將使用std::forward<T>(arg)有條件地轉發右值。

image_image的地址當然是不同的,因爲它們首先是不同的對象。如果QImage包含具有地址的對象,則可以驗證是否使用該地址移動了該對象。例如,如果你使用的std::vector<T>代替QImage你可以使用這樣的事情,以確定如果陣列感動:

void f(std::vector<T>&& v) { 
    std::cout << (v.empty()? 0: v.data()) << '\n'; 
    std::vector<T> other; 
    other = v; // will be copied 
    std::cout << (other.empty()? 0: v.data()) << '\n'; 
    other = std::move(v); // will be moved 
    std::cout << (other.empty()? 0: v.data()) << '\n'; 
} 
+0

謝謝您的回答!我現在明白了,一旦我們進入函數,右值基本上變成了一個正常變量(參考,儘管)。只存在於哪個函數被調用(採用正常參考值還是採用右值參考值)? 我也能夠通過改變它到'std :: cout <<(void *)image.bits()<< std :: endl;'輸出指針。這樣,如果我使用移動,指針地址是相等的,如果我不移動,則地址不相等。 – user1488118