2015-06-15 62 views
0

我有這樣的例子的代碼:的std ::移動到功能

#include <iostream> 

class Struct { 
public: 
    Struct() { std::cout << "0" << std::endl; } 
    Struct(Struct&) { std::cout <<"1"<<std::endl;} 
    Struct(const Struct&) { std::cout << "2" << std::endl; } 
}; 

class Struct2 { 
public: 
    Struct s; 

    Struct2() {} 
    void setMember(const Struct& aux) { s = aux; } 
}; 

int main() 
{ 
    Struct s; 
    Struct2 s2; 
    s2.setMember(s); 
} 
// http://coliru.stacked-crooked.com/a/dd57e8af23f6db4b 

懷疑1:

據printting 2 0,因爲在主構造和部件的構造Struct2的。

事情是,我期待三個0,因爲「setMember」正在接收's'的副本,對吧?那麼發生了什麼?

疑點二:

我想在把這個:

s2.setMember(std::move(s)); 

正如我不會用 'S' 一遍,但setMember不具有 '& &' 規定,可以嗎?我也必須這樣做嗎? :

s = std::move(aux); 

或者只是主要的一個就足夠了?

疑點三:

std::vector<A> vectorA; 

int main() 
{ 
    A a; 
    // modifies a ... 
    vectorA.push_back(std::move(a)); 
} 

它是正確的嗎?我是否在優化移動'a'的任何內容?它不會再被使用,我想保持它在矢量

感謝

+0

傳遞爭論作爲參考的參考是與作爲值(複製)傳遞完全相反的。在這裏,您的c.tros中沒有一個通過值來傳遞參數。 –

+0

如果你不理解傳遞引用機制,也許你應該在移動語義之前閱讀更多關於基本C++的知識。 – undu

回答

2

因爲「setMember」被接受的「的副本,對不對?

那麼,沒有。它正在收到一份const&並在作業操作員身上覆印。由於您沒有重載賦值運算符,因此不會打印任何內容。


s2.setMember(std::move(s));

這不會解決任何問題; std::move只會將s轉換爲右值,但在函數內部它仍然是const&


憑經驗:傳遞的價值,裏面搬走:

void setMember(Struct aux) { s = std::move(aux); } 

這樣,它就會 「自動地」 工作;複製接口上的左值/將右值移入參數值,然後將參數值移入實際的對象成員中。

當然,以使該機器的最佳利用,需要通過有一個右值,所以......

Struct s; 
Struct2 s2; 
s2.setMember(std::move(s)); 

或許...

s2.setMember(Struct()); 

這就是說,你的舊代碼不會中斷。


至於第三個例子,是的,這是確定的,altough我倒是可能要麼

  • 舉動的變化a到另一個功能,push_back(function())
  • 舉動的變化aA的構造函數和使用emplace_back
+0

那麼最終哪個是最有效的方法呢?我只是想把這個's'分配給s2的成員。 s2.setMember(std :: move(s))呢? – user3468999

+0

@ user3468999詳細闡述「高效」。如果你想避免拷貝,不要編寫導致拷貝的語句,我認爲它很簡單。要理解的關鍵是獲取價值並不一定要複製。所以我建議(取值)會很好。 –

+0

另外,我更新了第三個疑問的帖子,如果你可以檢查一下,請... ... :) – user3468999