2011-12-11 43 views
2

我想知道鑄造是否完全有必要。
我在這裏談論關於類之間的轉換,而不是基本類型。可以用一個好的設計完全避免使用?

正在鑄造(不管是C++風格,如static_castdynamic_cast,還是純C風格的鑄造)代碼的氣味?我可以看到有時它有幫助,但我認爲它也可以避免。鑄造是否會破壞任何OOP規則?

+0

完全避免投射不是一個明智的決定。良好的設計可以最大限度地減少它們,但避免它們會導致重新構建更糟糕的類型轉換形式。 – Pubby

回答

2

如果代碼味道你的意思,它應該在代碼審查提出一個標誌,那麼他們是一個代碼味道。如果你的意思是說他們永遠不應該出現在代碼中,那麼不,這裏有一些很好的用法。

對於一個有趣的例子(我總是覺得類型擦除有趣的),看看在需要dynamic_cast安全地從存儲的值讀取boost::any實施(不像union S其中,你必須猜測類型,並有限的)

素描:

struct any_base { 
    virtual ~any_base() {} 
}; 
template <typename T> 
struct any_data : any_base { 
    T value; 
    any_data(T const & value) : value(value) {} 
}; 
struct any { 
    any_base * data; 
    any() : data() {} 
    ~any() { delete data; } 

    template <typename T> 
    any(T const & v) : data(new any_data<T>(v) {} 
} 
template <typename T> 
T any_cast(any const & a) { 
    any_base<T> * p = dynamic_cast< any_base<T>* >(a.data); 
    if (!p) throw invalid_cast(); 
    return *p; 
} 
+0

如果你想讓任何數據成爲私人成員,你將如何解決這個問題,現在any_cast必須是朋友,但這不可能工作,因爲類型T在任何時候都不知道......所以這意味着任何::數據必須始終公開? – Gaff

3

不是特別的。儘可能避免演員陣容,但在最基本的層面上,C++區域存在於類型安全領域之外,並且演員陣容是必要的。 dynamic_cast是一個特殊的例外,具體而言,即使在堅實的OOP設計中,它也是必需的。

有「那是不完美的」,並且有「OMGWTF,Y你的DUMB」。演員陣容不完美。

+0

你能提供一個需要強制轉換的例子嗎? –

0

典型的例子是I/O:這是爲數不多的和唯一的原因投之一,它也使用在C中唯一合法的指針類型++中的一種:char *

uint32_t n; 
infile.read(reinterpret_cast<char *>(&n), sizeof n); 
n *= 2; 
outfile.write(reinterpret_cast<const char *>)(&n), sizeof n); 

其他「我/ O-like「操作需要類似的模式,例如加密或編碼轉換。

(在C++中的其他合法指針是void *在分配的上下文中使用時,但它不應該需要轉換:在C++方法到存儲器指針「轉換」到對象指針是通過施工void * addr = get_memory();,然後T * p = new (addr) T;

+0

我指的是類之間的轉換,而不是基本類型。 –

0

我要說的是,鑄造無法通過良好的設計完全避免的,因爲有合理的情況下,鑄造是一個不錯的選擇。代理非常有用,通常依賴於隱式或顯式的轉換,如下面的懶惰評估。

template <class fn_t, class result_t> 
class lazy_t { 
    fn_t fn_; 
public: 

    lazy_t(fn_t fn) : fn_ (fn) { } 

    operator result_t() { return fn_(); } 
}; 

在這種情況下,編譯器可以使用隱式轉換來執行給定函數的惰性評估。我會認爲轉換運算符是該類的公共接口的一部分。

dynamic_cast <>在某些情況下也是必要的,例如實施多派遣。有關詳情,請參閱http://en.wikipedia.org/wiki/Multiple_dispatch

有時候你的程序需要複雜的代碼。你不能總是堅持簡單,基本或「乾淨」的語言元素。

相關問題