2017-04-26 83 views
-2

我想創建功能,如:實現非複製交換功能

void func(sample &a){ 
    sample b(); 
    std::swap(b,a); 
} 

問題是,總是當我使用掉,然後拷貝構造函數的使用和析構函數被應用於交換功能使用的臨時對象。

是否有可能實現非複製交換?

+7

添加適當的移動構造函數並將賦值運算符移至'sample'。見「5條規則」。另外'樣本b();'是一個函數,參見「最令人頭痛的解析」。 – nwp

+1

您可以爲您自己的類型專門設置'std :: swap',或者在類型的名稱空間中提供'swap'的實現並通過ADL調用它。 – Quentin

+1

'a = sample();'似乎更適合BTW。 'a.clear()'會更好,我想。 – Jarod42

回答

2

您問題的C++ 11解決方案是在您的sample類中提供移動構造函數和移動賦值運算符。然後,std::swap將使用移動而不是複製操作,這應該是更有效的(你仍然會看到被調用的析構函數,但這通常會在「空」對象上,並且應該非常便宜)。

通常,如果你正在編寫你自己的拷貝構造函數和拷貝賦值操作符,那麼你還需要編寫一個移動構造函數和移動賦值操作符(當然也是析構函數) - 這是「5 「在C++ 11中,它擴展了從C++ 98中已知的」3規則「。例如,考慮這個(不好),例如類手工管理內存(NB這只是爲了說明一個例子,在現實生活中使用std::vectorstd::unique_ptr而不是做這個):

class example { 
public: 
    example() 
     : ptr{new int[1024]} 
    {} 

    example(const example& other) 
     : ptr{new int[1024]} 
    { 
     // Copy other's member array 
     std::copy(other.ptr, other.ptr + 1024, ptr); 
    } 

    example& operator=(const example& other) 
    { 
     if (this != &other) { 
      std::copy(other.ptr, other.ptr + 1024, ptr); 
     } 
     return *this; 
    } 

    ~example() 
    { 
     delete[](ptr); 
    } 

    example(example&& other) 
     : ptr(other.ptr) // "steal" other's ptr 
    { 
     other.ptr = nullptr; 
    } 

    example& operator=(example&& other) 
    { 
     std::swap(ptr, other.ptr); 
     return *this; 
    } 

private: 
    int* ptr; 
}; 

現在,當你 s,交換功能將使用移動操作,不會發生額外的分配,只需進行一些(便宜的)指針交換,以及對delete[](nullptr)的無操作調用。

-1

您的函數將a與默認構造的對象互換。如果這是預期的語義只是做

a = sample(); 

並提供移動構造函數和分配,因爲你認爲合適。