You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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并未检测到类型转换错误!

疑问

  1. 如何正确实现类型校验逻辑?
  2. 在对象指针以void*形式存储的场景下,这种类型校验是否可行?

补充说明

XmlLibObjectWrapper类的实现非常简单:

class XmlLibObjectWrapper 
{
public:
  // 注意:为消除XML库依赖,此处必须使用void*... 
  void* EngineObj;
}

内容的提问来源于stack exchange,提问作者dmitry_bond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:55:29