为什么C++ RTTI不像我期望的那样工作?[关闭]

ewm0tg9j  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(107)

**已关闭。**此问题需要debugging details。目前不接受回答。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答问题。
5天前关闭。
截至5天前,社区正在审查是否重新讨论这个问题。
Improve this question

注意:MRE示例太大,无法在此发布(!),因此我将其存储在我的Google Drive上,这里有一个链接-https://drive.google.com/uc?id=1BUDD2DhumdY2eVwO5BffyaQfjVIdABb3&export=download

我需要调整非常旧的lib,它使用Xerces(1.6)/Xalan(1.3)来使用新的Xerces(3.2.5)/Xalan(1.12)。
为了保持接口兼容,我必须在一些Xerces/Xalan对象上使用一个 Package 器类。 Package 器将Xerces/Xalan对象存储为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)
  {
    // I want it throw bad_cast here BUT IT DOES NOT!...
    //T& resultSpecific = dynamic_cast<T&>(*result); //<- this has the same problem
    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在这样的转换中没有看到任何问题!
能否请你的意见-我如何才能组织类型验证正确?如果这是可能的,在所有在这种情况下(当ptr到lib对象存储在一个形式的void*)?

注意:XmlLibObjectWrapper类非常简单,大致如下:

class XmlLibObjectWrapper 
{
public:
  // Note: to remove XML lib dependencies we have to use void* here... 
  void* EngineObj;
}

5gfr0r5j

5gfr0r5j1#

template<class T>
T* castAndCheck(const XmlLibObjectWrapper* pObjWrap)
{
  T* result = (T*)(pObjWrap->EngineObj);

字符串
不要使用C风格的强制转换。这里很可能是一个重新解释的强制转换
如果你做了一个重新解释的强制转换,而它不是一个正确的操作,你的程序将表现出未定义的行为。
要让RTTI工作,你必须从一个指向正确类型的对象的指针开始,即使它是一个基类型。
EngineObj是一个你没有告诉我们的类型,所以我不能直接修复你的代码。如果它是一个void*,那么就没有办法使用RTTI来修复你的问题。

相关问题