我正在重写一个项目,以便它使用getter和setter来引用TiXmlElement * 但是,我很快就遇到了与调试模式有关的问题:
从我班级的标题中得知:
TiXmlElement *_rootElement;
TiXmlElement *_dialogsElement;
TiXmlElement *_dialogElement;
TiXmlDocument _document;
void setDocument (TiXmlDocument doc) { this->_document = doc; }
void setRootElement (TiXmlElement * element) { this->_rootElement = element; }
void setDialogsElement (TiXmlElement * element) { this->_dialogsElement = element; }
TiXmlDocument getDocument () { return this->_document; }
TiXmlElement* getRootElement () { return this->_rootElement; }
TiXmlElement* getDialogsElement () { return this->_dialogsElement; }
摘自类构造函数:
DCXML::DCXML(const char *dialogMark,const char *dialogName,TiXmlDocument doc) {
...
this->setDocument(doc);
this->setRootElement(this->getDocument().FirstChildElement("dcxml"));
this->setDialogsElement(this->getRootElement()->FirstChildElement("dialogs"));
摘录实例化课程:
TiXmlDocument doc(input.gettok(2,"\"").to_chr());
bool dcxmlFile = doc.LoadFile();
...
DCXML *dcxml = new DCXML(input.gettok(2).to_chr(),input.gettok(3).to_chr(),doc);
现在是奇怪的部分。这一直到
this->setDialogsElement(this->getRootElement()->FirstChildElement("dialogs"));
在构造函数中。
- >在调试模式下,FirstChildElement(“dialogs”)在VS2008中抛出“CXX0039:错误:符号不明确”错误。
奇怪的部分是IntelliSense选择FirstChildElement方法,编译器不会抛出任何错误。
甚至更奇怪的是,在发布模式下,它只是无声地失败以获取对话框元素。
我做错了什么?或者,如果你已经成功实现了TiXmlElement *的getter setter包装器,请告诉我我的能力!。
这里有完整的参考资料摘自XML文件:
<?xml version="1.0" encoding="utf-8"?>
<dcxml>
<dialogs>
<dialog
name="mediaplayer"
center=""
w="300"
h="400"
caption="Mamp 4.0 BETA"
border="btmnzy">
</dialog>
</dialogs>
</dcxml>
当我处于死胡同时,反馈将非常受欢迎:)
答案 0 :(得分:2)
确保
TiXmlDocument getDocument () { return this->_document; }
不会深层复制其包含的TiXmlElement。否则你返回一个临时的,在构造函数中使用它来设置根节点,然后根节点就会被破坏。我没有查看它的API,但只是意识到这些陷阱。
调用模糊的原因是:
FirstChildElement
有三个重载带有一个参数:
const TiXmlElement * FirstChildElement (const char *value) const // :1
const TiXmlElement * FirstChildElement (const std::string &_value) const // :2
TiXmlElement * FirstChildElement (const std::string &_value) // :3
您可以通过TiXmlElement&
(使用TiXmlElement*
指针)访问TiXmlElement。但采用const char*
的版本具有隐式对象参数TiXmlElement const&
。也就是说,需要进行资格转换才能使呼叫工作。对于采用std::string const&
的其他版本,也需要进行转换:
<implied obj param> <implicit obj param> <arg1> <param1>
TiXmlElement& TiXmlElement const& char const* char const* // :1
TiXmlElement& TiXmlElement const& char const* std::string const& // :2
TiXmlElement& TiXmlElement& char const* std::string const& // :3
第一次和第三次重载之间存在歧义。一个简单的解决方法是
this->setDialogsElement(
this->getRootElement()->FirstChildElement(std::string("dialogs")));
相反,它将调用最后一个版本。另一个解决方法是const_cast:
this->setDialogsElement(
const_cast<TiXmlElement const*>(this->getRootElement())->
FirstChildElement("dialogs"));
将调用第一个版本。至于为什么它只发生在DEBUG ...我记得TiXML有一个选项来禁用STL的使用。也许在发布模式下你禁用了它(因此重载了std::string
),但是在调试模式下你忘记了吗?