TiXmlElement* 的 getter 和 setter 包装器

发布于 2024-07-10 15:50:22 字数 2050 浏览 11 评论 0原文

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

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

I am rewriting a project so that it uses getters and setters to reference the TiXmlElement *'s
However, I quickly run into problems that seem to be related to debug mode:

Ecxerpt from my class's header:

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; }

Excerpt from class constructor:

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"));

Excerpt from instantiating the class:

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);

Now for the weird part. This works up until

this->setDialogsElement(this->getRootElement()->FirstChildElement("dialogs"));

in the constructor.

->FirstChildElement("dialogs") throws an "CXX0039: Error: symbol is ambiguous" error in VS2008 when in debug mode.

The weird part is IntelliSense picks up on the FirstChildElement method and the compiler doesn't throw any errors.

What's even weirder is that when in release mode it just fails silently to get the dialogs element.

What I am doing wrong ? Or if you have succesfully implemented getter setter wrappers for TiXmlElement*'s let me know how I can as well!.

For complete reference here's an excerpt from the XML file:

<?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>

Feedback would be much appreciated as I am at a dead end :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亣腦蒛氧 2024-07-17 15:50:22

确保

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 ),但在调试模式下您忘记了?

Make sure that

TiXmlDocument getDocument () { return this->_document; } 

Will not deep copy its contained TiXmlElement's. Otherwise you return a temporary, use that in the constructor to set the root node, which then will be destructed already. I haven't looked in its API, but just be aware of such pitfalls.

The reason for the ambiguous call is because:

There are three overloads of FirstChildElement taking one argument:

const TiXmlElement *    FirstChildElement (const char *value) const // :1
const TiXmlElement *    FirstChildElement (const std::string &_value) const // :2
TiXmlElement       *    FirstChildElement (const std::string &_value) // :3

You access the TiXmlElement through TiXmlElement& (using a TiXmlElement* pointer). But the version taking a const char* has an implicit object parameter of TiXmlElement const&. That is, a qualification conversion is required to make the call work. For the other versions taking a std::string const&, there are conversions required too:

<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

There is an ambiguity between the first and the third overload. An easy fix is to do

this->setDialogsElement(
    this->getRootElement()->FirstChildElement(std::string("dialogs")));

Instead, which will call the last version. Another fix is to const_cast:

this->setDialogsElement(
    const_cast<TiXmlElement const*>(this->getRootElement())->
        FirstChildElement("dialogs"));

Which will call the first version. As for why it only happens in DEBUG... I remember that TiXML has an option to disable the use of the STL. Maybe in release mode you disabled it (and thus the overloads taking std::string), but in debug mode you forgot?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文