最近我發現了一個很好的例子,說明爲什麼C風格演員是壞的。我們先從下面的類實現多個COM接口(我有兩個爲簡潔,但在實際生活中有十):有什麼嚴酷的例子顯示C風格的演員是壞的?
class CMyClassInitial : public IInterface1, public IInterface2 {
//declarations omitted
};
HRESULT CMyClassInitial::QueryInterface(REFIID iid, void** ppv)
{
if(ppv == 0) {
return E_POINTER;
}
*ppv = 0;
if(iid == __uuidof(IUnknown) || iid == __uuidof(IInterface1)) {
*ppv = (IInterface1*)this;
} else if(iid == __uuidof(IInterface2)) {
*ppv = (IInterface2*)this;
} else {
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
以上實現使用C-類型轉換爲adjusting pointers to account for multiple inheritance。他們甚至可以按照static_cast
s - this
的指針值進行適當的調整。
現在我們複製粘貼(或者我應該說重用代碼的?)相同的QueryInterface()
執行到一些其他非常相似的類。
class CMyClassModified : public IInterface1 {
//declarations omitted
};
並保持實施相同。新的類不從IInterface2
了繼承,但
} else if(iid == __uuidof(IInterface2)) {
*ppv = (IInterface2*)this;
}
會編得很好,C樣式轉換將作爲reinterpret_cast
- this
指針值將被原樣複製。 調用者將獲得一個指向實際上沒有實現的對象的指針IInterface2
- 未定義行爲的直接方式。這樣的問題很難在龐大的數據庫中發現,並且當有很多(不是我的例子中的兩個)接口時。
如果static_cast
使用,不會發生 - 編譯器會發出錯誤試圖編譯
*ppv = static_cast<IInterface2*>(this);
IMO這是如何使用C-風格轉換可能會導致嚴重的問題的惡劣足夠的例子。
還有其他的例子嗎?
一個偉大的疑難雜症,但我不能完全肯定這是適合左右。這似乎很討論。充其量,這是一個社區維基。 – tenpn 2011-02-03 10:25:16
@tenpn:我沒有看到這裏可以討論什麼 - 只是在C++中用自己的腳步拍攝的一個例子。 – sharptooth 2011-02-03 10:28:46