2012-08-03 52 views
7

我花了相當多的時間來實現我的類的移動語義,但現在我正在處理使用它的函數。移動語義和常量引用

好吧,所以我有這個對象有很多關於堆的數據:CLargeOb爲此我實現了移動語義(構造函數和運算符=)。它非常像這樣使用:

void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

但是它並不總是能夠使物體移動/看不上,所以我加了這兩個功能:

void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = largeOb1; 
    m_largeOb2 = (CLargeOb&&)largeOb2; 
} 

void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2) 
{ 
    SomeOtherFunc(largeOb1); 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; 
    m_largeOb2 = largeOb2; 
} 

雖然它的工作原理,你已經可以當我有一個函數需要3個或更多的這些對象作爲參數時,猜測它將成爲* ss中的一個主要難點......是不是有一種巧妙的方法來使用模板或者「完美轉發」來解決這個問題?

+0

@MooingDuck:在VS2010中工作正常,沒問題。要調用operator =(&&),必須使用std :: move或者&& cast來顯式調用它。但是當然,下面提供的解決方案要好得多。 – demorge 2012-08-03 21:40:15

+0

@demorge:哦對,我完全忘記了規則的改變。對不起, – 2012-08-03 21:45:00

+1

請寫'std :: move(largeOb1)'而不是'(CLargeOb &&)largeOb1'。幾代程序員將會感謝您使用標準的C++ 11方法來實現移動,而不是非慣用和邊界不可讀的C/C++混合。 – fredoverflow 2012-08-04 12:15:41

回答

15

和C++ 03一樣,指南是:如果你想要一個副本,把它放在參數列表中。

這讓打進電話的處理,你怎麼弄的對象,你只是得到一個對象不分:

void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = std::move(largeOb1); // save as members and trash the originals 
    m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast) 
} 

來電者:

OtherOb o; 

CLargeOb x, y; 
const CLargeOb z; 

o.Func(x, std::move(y)); // need x for later, done with y so move it 
o.Func(std::move(x), z); // done with x, necessarily copy z 

這僅僅是幾個專門的重載高效。爲什麼? 因爲那些作爲構造函數已經存在。讓編譯器找出在呼叫站點爲你調用哪一個,它已經知道該怎麼做。

+2

我喜歡它,太簡單了! – demorge 2012-08-03 21:37:18

+0

這不會移動兩次,而不是一次? (注意:當然,另外一個步驟應該幾乎不會引起注意,所以我已經向上投票了) – Sjoerd 2012-08-03 22:51:46

+0

@Sjoerd:是的,希望編譯器會在某個地方取消某個移動;正如你所說,即使它沒有,也沒有關係。 – GManNickG 2012-08-03 22:56:52