2015-05-16 34 views
0

在我的一些類中實現方法和運算符重載以利用C++中的右值引用時,通常會編寫一些違反DRY原則的糟糕設計的代碼。下面的代碼片段會是更好的替代方案嗎? (此代碼只是爲了說明問題)如何在不違反C++ DRY原則的情況下實現可移動重載?

class matrix_2_2 
{ 
    int _m[2][2]; 

public: 

    matrix_2_2 operator*(const matrix_2_2& m) const & 
    { 
     matrix_2_2 res; 
     for(int i = 0 ; i < 2 ; i ++) 
      for(int j = 0 ; j < 2 ; j++) 
       for(int k = 0 ; k < 2 ; k++) 
        res._m[i][j] = (res._m[i][j] + _m[i][k]*m._m[k][j]); 

     return res; 
    } 

    matrix_2_2 operator*(matrix_2_2&& m) && 
    { 
     matrix_2_2 res; 
     for(int i = 0 ; i < 2 ; i ++) 
      for(int j = 0 ; j < 2 ; j++) 
       for(int k = 0 ; k < 2 ; k++) 
        res._m[i][j] = (res._m[i][j] + _m[i][k]*m._m[k][j]); 

     return move(res); 
    } 

此代碼呈現了大量的重複的實現細節,我想封裝邏輯,並在不同的重載重用,又不失因爲移動優勢左值來左值隱含轉換。

+0

您可以定義第三個函數並將兩個'operator *'調用到它中。 – Lingxi

+0

@靈溪,在這種情況下,我會傳遞'const matrix_2_2&'或'matrix_2_2 &&'?我想到了這種替代方案,但無法就傳遞函數的類型得出任何結論。 – LunaticSoul

+0

對於這種情況,您不需要重載。 –

回答

5

一個更好的選擇是隻刪除右值合格operator*完全和剛纔的一個operator*,這一個:

matrix_2_2 operator*(const matrix_2_2& m) const; 

你的類是POD - 有一個舉措,之間沒有區別在這種情況下複製,所以利用移動語義來獲得優勢沒有任何好處。你正在獲得代碼複雜性,但不是在性能上。真的是你的代碼應該怎麼做,如果this&&&沒有邏輯上的區別...

而且,這樣的:

matrix_2_2 operator*(matrix_2_2&& m) && 
{ 
    matrix_2_2 res; 
    ... 
    return std::move(res); 
} 

是不寫正確的方式,作爲最後move品牌它不可能做到的命名返回值優化,讓你做一個額外的move像代碼:

matrix_2_2 product = some_matrix() * some_other_matrix(); 

而不是簡單地構建res就地在product

+0

好的,在這個例子中,類是一個POD,但是在一個更復雜的情況下,它不會是,我想知道一個更好的設計,用於在不同的過載中重用核心實現細節,同時也利用右值優化。 – LunaticSoul

+0

關於'return std :: move(res);'我不知道這會傷害返回值優化,謝謝你的提示。 – LunaticSoul

+2

@LunaticSoul如果你有一個更復雜的應用移動語義的場景,我只會問一個關於這個場景的問題。當然,如果你發現自己寫*相同的*代碼,你可以很容易地刪除重複。 – Barry

相關問題