我想知道鑄造是否完全有必要。
我在這裏談論關於類之間的轉換,而不是基本類型。可以用一個好的設計完全避免使用?
正在鑄造(不管是C++風格,如static_cast
或dynamic_cast
,還是純C風格的鑄造)代碼的氣味?我可以看到有時它有幫助,但我認爲它也可以避免。鑄造是否會破壞任何OOP規則?
我想知道鑄造是否完全有必要。
我在這裏談論關於類之間的轉換,而不是基本類型。可以用一個好的設計完全避免使用?
正在鑄造(不管是C++風格,如static_cast
或dynamic_cast
,還是純C風格的鑄造)代碼的氣味?我可以看到有時它有幫助,但我認爲它也可以避免。鑄造是否會破壞任何OOP規則?
如果代碼味道你的意思,它應該在代碼審查提出一個標誌,那麼他們是一個代碼味道。如果你的意思是說他們永遠不應該出現在代碼中,那麼不,這裏有一些很好的用法。
對於一個有趣的例子(我總是覺得類型擦除有趣的),看看在需要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;
}
如果你想讓任何數據成爲私人成員,你將如何解決這個問題,現在any_cast必須是朋友,但這不可能工作,因爲類型T在任何時候都不知道......所以這意味着任何::數據必須始終公開? – Gaff
不是特別的。儘可能避免演員陣容,但在最基本的層面上,C++區域存在於類型安全領域之外,並且演員陣容是必要的。 dynamic_cast
是一個特殊的例外,具體而言,即使在堅實的OOP設計中,它也是必需的。
有「那是不完美的」,並且有「OMGWTF,Y你的DUMB」。演員陣容不完美。
你能提供一個需要強制轉換的例子嗎? –
典型的例子是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;
)
我指的是類之間的轉換,而不是基本類型。 –
我要說的是,鑄造無法通過良好的設計完全避免的,因爲有合理的情況下,鑄造是一個不錯的選擇。代理非常有用,通常依賴於隱式或顯式的轉換,如下面的懶惰評估。
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。
有時候你的程序需要複雜的代碼。你不能總是堅持簡單,基本或「乾淨」的語言元素。
完全避免投射不是一個明智的決定。良好的設計可以最大限度地減少它們,但避免它們會導致重新構建更糟糕的類型轉換形式。 – Pubby