1

我正在重写一个项目,以便它使用 getter 和 setter 来引用 TiXmlElement *'s 但是,我很快遇到了似乎与调试模式有关的问题:

摘自我班的标题:

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: Error: symbol is ambiguous”错误。

奇怪的部分是 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>

反馈将不胜感激,因为我处于死胡同:)

4

1 回答 1

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 。但是采用 a 的版本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),但在调试模式下你忘记了?

于 2008-12-17T12:04:16.183 回答