2011-04-27 95 views
1

我有一個函數接口:避免拷貝初始化時參考

struct iFace { 
    virtual Type& getType() = 0; 
} 

和想法是檢索它喜歡:

iFace& iface = getIface(); 
Type& type = iface.getType(); 

然而,我偶爾我做了錯誤,並寫上:

Type type = iface.getType(); 

哪個按值複製,這​​是我想要避免。但是,當我犯這樣的錯誤時,編譯器不會因爲它的合法語法而發出警告。我想爲此觸發編譯時錯誤,問題我的替代方法是什麼?

我想過聲明拷貝構造函數,但沒有在任何地方定義它,如果它的使用造成的鏈接時錯誤,但後來我將無法使用拷貝構造函數任何情況,小於desiderable

+0

你無法真正擁有它。 – 2011-04-27 21:18:47

+0

這就是我所害怕的,所以我想在這裏要求確認。感謝您的確認 – lurscher 2011-04-27 21:20:02

+0

這取決於類型是什麼。如果你可以使類型抽象,那麼你將無法創建一個實例。 – 2011-04-27 22:09:40

回答

8

通過將複製構造函數和賦值運算符置於「private」下使iFace不可複製。然後提供一個明確的Copy方法。

class Type { 
public: 
    virtual Copy(Type& dest) = 0; 
private: 
    Type (const Type &) {assert(false)} 
    Type & operator=(const Type &) {assert(false)} 
} 

您也可以使用boost noncopyable做同樣的事情(其實施如上)。

所以,如果你想你的代碼複製,你會怎麼做

Type& type = iface.getType(); 
Type typeCpy; 
type.Copy(typeCpy); 

順便說一句 - 我想補充一點,如果你這樣做是因爲性能問題,你一定優化器沒有按爲你擺脫臨時副本?

+0

這屬於複製構造函數變得不太可用的情況。讓我們保持這個計劃「如果一切都失敗」 – lurscher 2011-04-27 21:18:26

+0

@lurscher,你也可以提供一個明確的副本,看看我的編輯。 – 2011-04-27 21:19:47

+0

我們可以使用顯式關鍵字來限制複製構造函數嗎? – lurscher 2011-04-27 21:21:32

-1

在這裏返回一個指針似乎是合理的,但如果讓所有權感到困惑,您可以返回一個包含引用的包裝。

struct Class { 
    struct Ref { 
     Ref(Class& c_) : c(c_) { } 
     Class Clone() { return c; } 
     // overload -> to provide access to c 
     private: 
     Class& c; 
    }; 
}; 

原始類可以正常複製,但必須明確地做引用。我對這個想法並不滿意(我認爲應該少一個用戶不認識複製語義如何工作的人,而不是那些意外地持有這些太長時間的人),但理論上這是可行的。