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

ewm0tg9j  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(121)

**已关闭。**此问题需要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添加一个类型转换验证。但是出了问题...
下面是一个转换验证函数的代码:

  1. template<class T>
  2. T* castAndCheck(const XmlLibObjectWrapper* pObjWrap)
  3. {
  4. T* result = (T*)(pObjWrap->EngineObj);
  5. #ifdef _CPPRTTI
  6. const type_info& ti = typeid(*result);
  7. const type_info& tiExpected = typeid(T);
  8. if (ti != tiExpected)
  9. {
  10. // I want it throw bad_cast here BUT IT DOES NOT!...
  11. //T& resultSpecific = dynamic_cast<T&>(*result); //<- this has the same problem
  12. T* resultSpecific = dynamic_cast<T*>(result);
  13. if (resultSpecific == NULL)
  14. throw XmlApiError(
  15. ParametrizedMessage("invalid type-cast: expect @1@ but got object of @2@ class")
  16. << tiExpected.name() << ti.name(),
  17. 0, 0, CException::sl_Operational, _ERR_FLINE_);
  18. }
  19. #endif
  20. return result;
  21. }
  22. DOMNode* castToDomNode(const XmlLibObjectWrapper* pObjWrap)
  23. {
  24. return castAndCheck<DOMNode>(pObjWrap);
  25. }
  26. DOMElement* castToDomElement(const XmlLibObjectWrapper* pObjWrap)
  27. {
  28. return castAndCheck<DOMElement>(pObjWrap);
  29. }
  30. XercesDOMParser* castToParser(const XmlLibObjectWrapper* pObjWrap)
  31. {
  32. return castAndCheck<XercesDOMParser>(pObjWrap);
  33. }

字符串
下面是一个测试用例代码:

  1. // [...]
  2. DOMDocument* dom = parser->getDocument();
  3. // [...]
  4. DOMElement* root = dom->getDocumentElement();
  5. XmlLibObjectWrapper* wrp = new XmlLibObjectWrapper(root);
  6. DOMNode* pn1 = castToDomNode(wrp);
  7. DOMElement* pe1 = castToDomElement(wrp);
  8. XercesDOMParser* xp = castToParser(wrp);


不幸的是-没有例外!所以,<...>DOMElement* 到XercesDOMParser* 的dynamic_cast在这样的转换中没有看到任何问题!
能否请你的意见-我如何才能组织类型验证正确?如果这是可能的,在所有在这种情况下(当ptr到lib对象存储在一个形式的void*)?

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

  1. class XmlLibObjectWrapper
  2. {
  3. public:
  4. // Note: to remove XML lib dependencies we have to use void* here...
  5. void* EngineObj;
  6. }

5gfr0r5j

5gfr0r5j1#

  1. template<class T>
  2. T* castAndCheck(const XmlLibObjectWrapper* pObjWrap)
  3. {
  4. T* result = (T*)(pObjWrap->EngineObj);

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

相关问题