2012-05-06 50 views
4

有沒有辦法允許移動構造函數和不允許複製構造和分配。我可以考慮使用文件指針和緩衝區指針(資源句柄等)的幾個類,這些類將受益於構建和分配副本。如何允許移動建築和不允許分配和複製建築類

我正在使用VC2010 & GCC 4.5.2。我知道我必須在VC2010類頭文件中聲明空的專用賦值和複製構造函數,並且據我所知,GCC允許某種形式的刪除簽名,該方法執行相同的操作。

如果有人有這樣一個骨架類的好例子,我會非常感謝的優點。 在此先感謝 約翰

這是一個類,我想允許移動,但我也想防止直接asssignment的例子。難道這是複製構造函數和operator = private的問題嗎?

class LoadLumScanner_v8002 : public ILoadLumScanner { 
public: 
// default constructor 
LoadLumScanner_v8002(); 

// copy constructor 
LoadLumScanner_v8002(const LoadLumScanner_v8002& rhs); 

// move constructor 
LoadLumScanner_v8002(LoadLumScanner_v8002&& rhs); 

// non-throwing copy-and-swap idiom unified assignment 
inline LoadLumScanner_v8002& operator=(LoadLumScanner_v8002 rhs) { 
    rhs.swap(*this); 
    return *this; 
} 

// non-throwing-swap idiom 
inline void swap(LoadLumScanner_v8002& rhs) throw() { 
    // enable ADL (not necessary in our case, but good practice) 
    using std::swap; 
    // swap base members 
    // ... 
    // swap members 
    swap(mValidatedOk, rhs.mValidatedOk); 
    swap(mFile, rhs.mFile); 
    swap(mPartNo, rhs.mPartNo); 
    swap(mMediaSequenceNo, rhs.mMediaSequenceNo); 
    swap(mMaxMediaSequenceNo, rhs.mMaxMediaSequenceNo); 
    swap(mLoadListOffset, rhs.mLoadListOffset); 
    swap(mFirstLoadOffset, rhs.mFirstLoadOffset); 
    swap(mLoadCount, rhs.mLoadCount); 
    swap(mLoadIndex, rhs.mLoadIndex); 
    swap(mLoadMediaSequenceNo, rhs.mLoadMediaSequenceNo); 
    swap(mLoadPartNo, rhs.mLoadPartNo); 
    swap(mLoadFilePath, rhs.mLoadFilePath); 
} 

// destructor 
virtual ~LoadLumScanner_v8002(); 
} 

回答

9

你提到的兩種解決方案都可以正常工作。

1.

class MoveOnly 
{ 
    MoveOnly(const MoveOnly&); 
    MoveOnly& operator=(const MoveOnly&); 
public: 
    MoveOnly(MoveOnly&&); 
    MoveOnly& operator=(MoveOnly&&); 
}; 

2.

class MoveOnly 
{ 
public: 
    MoveOnly(const MoveOnly&) = delete; 
    MoveOnly& operator=(const MoveOnly&) = delete; 
    MoveOnly(MoveOnly&&); 
    MoveOnly& operator=(MoveOnly&&); 
}; 

的 「=刪除」 簽名是新與C++ 11(由於是右值參考)的裝置,以及基本上相同的東西C++ 03技術(聲明私有並且不定義)。 C++ 11解決方案的優點在於,它肯定會在編譯時發現錯誤,而不會延遲到鏈接時間。

您的編譯器可能還不支持「= delete」,在這種情況下,您必須回退第一個解決方案。

第三個解決方案是默認的複製成員:

class MoveOnly 
{ 
public: 
    MoveOnly(MoveOnly&&); 
    MoveOnly& operator=(MoveOnly&&); 
}; 

當一個移動的特殊成員被聲明,是否拖欠或沒有,那麼編譯器將隱添加刪除副本成員如果不另有聲明它們。您的編譯器可能會或可能不會實現此功能。

+3

我喜歡'= delete'解決方案,因爲它明確地表明它不僅意味着將任何人的定義遺漏給後面的人讀取。 – Flexo

相關問題