最近我发现了一个很好的例子,说明为什么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