我正在重写一个项目,以便它使用getter和setter来引用TiXmlElement *的
但是,我很快遇到了似乎与 Debug模式有关的问题:
从我类(class)的标题摘录:
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"));
在构造函数中。
->在 Debug模式下,VS2008中的FirstChildElement(“dialogs”)在VS2008中引发“CXX0039:错误:符号不明确”错误。
奇怪的是,IntelliSense会选择FirstChildElement方法,并且编译器不会引发任何错误。
甚至更奇怪的是,在 Release模式下,它只是默默地无法获取dialogs元素。
我做错了什么?或者,如果您已经成功地为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>
反馈将不胜感激,因为我处于死胡同:)
最佳答案
确保
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&
。也就是说,需要进行资格转换才能使 call 正常进行。对于采用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。也许在 Release模式下您禁用了它(并因此禁用了
std::string
的重载),但是在 Debug模式下您忘记了?