TiXmlElement *的getter和setter包装器

时间:2008-12-17 11:44:11

标签: c++ tinyxml

我正在重写一个项目,以便它使用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>

当我处于死胡同时,反馈将非常受欢迎:)

1 个答案:

答案 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),但是在调试模式下你忘记了吗?