2013-05-28 77 views
6

我讀的C++設計模式及衍生馬克喬希定價和執行他在C++ 11的代碼。在我討論虛擬拷貝構造函數的第4章之前,一切都很順利。C++ 11的虛擬拷貝構造函數

PayOffDoubleDigital thePayOff(Low, Up); 
VanillaOption theOption(thePayOff, Expiry); 

的這裏的問題是,VanillaOption包含thePayOff參考。如果是這樣的話,有人修改thePayOfftheOption的行爲是可以不知不覺地修改。他建議的解決方案是建立在PayOffDoubleDigital的基類的虛擬拷貝構造函數,PayOff使theOption包含它自己的拷貝:

virtual PayOff* clone() const = 0; 

,然後在每個繼承類中定義:

PayOff* PayOffCall::clone() const 
{ 
    return new PayOffCall(*this); 
} 

返回新引入了我作爲C++ 11中可能不合適的東西。那麼使用C++ 11處理這個問題的正確方法是什麼?

+3

零規則:使用正確的所有權語義來創建句柄類並在任何地方使用。 –

+0

看起來我有一些額外的研究。謝謝你,馬丁霍。 – BDig

+0

我之前寫過:http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html –

回答

11

他建議的解決方案是建立在PayOffDoubleDigital的基類的虛擬拷貝構造函數[...]

首先,clone()不是拷貝構造函數。爲X A類拷貝構造函數是與通常的簽名沒有返回類型的特殊成員函數:

X(X const&) 

而且可能有簽名:

X(X&) 

功能clone()只是一個普通的(虛擬)功能,其特殊的含義是由你的認可 - 用戶 - 如一些東西,爲您創建對象的克隆,而不是由編譯器,不知道什麼clone()一樣。

返回新抓住了我的東西可能在不適當C++ 11

這是真的,用new是不是在C++ 11地道。事實上,在C++ 11中,除非你正在進行低層次的內存管理,否則你幾乎不應該使用new(除非你真的需要必須避免的東西),而在C++ 14中,你可以刪除「差不多」。不幸的是,這很可能是在需要new特例。

我會這麼說,因爲我相信返回unique_ptr聽起來像適當的事情在這裏做(選擇對象必須保持自己的PayOff對象,就像只要選擇的對象是活必須活下去) ,並且在C++ 11沒有std::make_unique()函數(它會在那裏在C++ 14):

std::unique_ptr<PayOff> PayOffCall::clone() const 
{ 
    return std::unique_ptr<PayOff>(new PayOffCall(*this)); 
} 

具有VanillaOption(或它的基類)持有unique_ptr而不是原始指針將使它不需要deletePayOff對象由clone()返回。反過來,不需要delete那個對象意味着不需要定義一個用戶提供的析構函數,也不需要關心Rule of ThreeRule of Five或什麼。

只要你可以,請按照R. Martinho's Fernandes's advice並去Rule of Zero

+0

謝謝你的好評。這是一個很難掌握的C++領域。如果可以的話,我會標記出來。但是,這是我的第一個問題,我沒有必要的聲望。需要更多的人來標記這個問題:) – BDig

+0

@BDig:不要擔心,繼續問好問題,你會很快得到的代表:)很高興我能幫助,並與您的書好運 –

0

由於經常與所有權打交道時,最乾淨的解決方案是返回一個智能指針:它既保證異常安全(沒有內存泄漏的風險),並使其由誰來明確的對象所有。

無論您需要使用unique_ptrshared_ptr完全取決於你。