假設我有一類實施幾個接口爲什麼選擇static_cast而不是隱式轉換鏈?
class CMyClass : public IInterface1, public IInterface2 { };
並且在I類需要獲得void*
指針這些接口中的一個(典型情況IUnknown::QueryInterface()
的成員函數。
典型的解決方案是使用static_cast
實現指針調整:
void* pointer = static_cast<IInterface2*>(this);
,它是在這種情況下,安全的,如果沒有已知的CLAS從CMyClass
繼承。但是,如果這樣的類存在:
class CDerivedClass : public CUnrelatedClass, public CMyClass {};
我accidentially做
void* pointer = static_cast<CDerivedClass*>(this);
和this
實際上是指向CMyClass
實例的編譯器不會趕上我,以後的程序可能會遇到不確定的行爲 - static_cast
變得不安全。
建議的解決方案是使用隱式轉換:
IInterface2* interfacePointer = this;
void* pointer = interfacePointer;
看起來這將解決這兩個問題 - 指針調整和無效垂頭喪氣的風險。
第二種解決方案是否存在問題?有什麼可以選擇第一個的原因?
它有趣的是`CMyClass`具有CDerivedClass`的`知識在這裏......不是不可能的,甚至不是一個真正可怕的設計的跡象,但在一般情況下,`CMyClass`不應該有任何的知識後人。我可以想象在頭文件中定義了這兩個類,在定義了`CMyClass`方法的翻譯單元中包含了這兩個類,在VS中它更傾向於提倡預編譯頭文件...仍然是值得思考的。 – 2011-02-10 09:13:58