为何C++ RTTI未按预期工作?Xerces升级类型校验异常
问题描述
我正在将依赖老旧Xerces(1.6)/Xalan(1.3)的库迁移至新版Xerces(3.2.5)/Xalan(1.12),原有代码几乎无法用现代Microsoft C++编译器和STL编译是迁移的主要原因。为保持接口兼容性,我为部分Xerces/Xalan对象编写了包装类XmlLibObjectWrapper,该类通过void*存储对象实例。我尝试借助RTTI实现类型转换校验,但遇到了问题。
类型转换校验函数代码
template<class T> T* castAndCheck(const XmlLibObjectWrapper* pObjWrap) { T* result = (T*)(pObjWrap->EngineObj); #ifdef _CPPRTTI const type_info& ti = typeid(*result); const type_info& tiExpected = typeid(T); if (ti != tiExpected) { // 我希望在此抛出bad_cast,但并未生效!... //T& resultSpecific = dynamic_cast<T&>(*result); //<- 存在同样问题 T* resultSpecific = dynamic_cast<T*>(result); if (resultSpecific == NULL) throw XmlApiError( ParametrizedMessage("invalid type-cast: expect @1@ but got object of @2@ class") << tiExpected.name() << ti.name(), 0, 0, CException::sl_Operational, _ERR_FLINE_); } #endif return result; } DOMNode* castToDomNode(const XmlLibObjectWrapper* pObjWrap) { return castAndCheck<DOMNode>(pObjWrap); } DOMElement* castToDomElement(const XmlLibObjectWrapper* pObjWrap) { return castAndCheck<DOMElement>(pObjWrap); } XercesDOMParser* castToParser(const XmlLibObjectWrapper* pObjWrap) { return castAndCheck<XercesDOMParser>(pObjWrap); }
测试用例代码
// [...] DOMDocument* dom = parser->getDocument(); // [...] DOMElement* root = dom->getDocumentElement(); XmlLibObjectWrapper* wrp = new XmlLibObjectWrapper(root); DOMNode* pn1 = castToDomNode(wrp); DOMElement* pe1 = castToDomElement(wrp); XercesDOMParser* xp = castToParser(wrp);
异常现象
测试中未触发任何异常:将DOMElement*强制转换为XercesDOMParser*时,dynamic_cast并未检测到类型转换错误!
疑问
- 如何正确实现类型校验逻辑?
- 在对象指针以
void*形式存储的场景下,这种类型校验是否可行?
补充说明
XmlLibObjectWrapper类的实现非常简单:
class XmlLibObjectWrapper { public: // 注意:为消除XML库依赖,此处必须使用void*... void* EngineObj; }
内容的提问来源于stack exchange,提问作者dmitry_bond
相关产品推荐
相关产品推荐

