**已关闭。**此问题需要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;
}
型
1条答案
按热度按时间5gfr0r5j1#
字符串
不要使用C风格的强制转换。这里很可能是一个重新解释的强制转换。
如果你做了一个重新解释的强制转换,而它不是一个正确的操作,你的程序将表现出未定义的行为。
要让RTTI工作,你必须从一个指向正确类型的对象的指针开始,即使它是一个基类型。
EngineObj
是一个你没有告诉我们的类型,所以我不能直接修复你的代码。如果它是一个void*
,那么就没有办法使用RTTI来修复你的问题。