代码之家  ›  专栏  ›  技术社区  ›  Martijn Laarman

TixmlElement*的getter和setter包装器

  •  1
  • Martijn Laarman  · 技术社区  · 16 年前

    我正在重写一个项目,以便它使用getter和setter引用tixmlement*的 但是,我很快就会遇到与调试模式相关的问题:

    ecxerpt从我的类标题:

    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方法上得到了支持,编译器不会抛出任何错误。

    更奇怪的是,当处于释放模式时,它只会默默地失败,无法获取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>
    

    感谢您的反馈,因为我处于一个死胡同:)

    1 回复  |  直到 13 年前
        1
  •  2
  •   Johannes Schaub - litb    16 年前

    确保

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

    不会对其包含的tixmlement进行深度复制。否则返回一个临时的,请在构造函数中使用它来设置根节点,然后根节点将被销毁。我没有查看它的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
    

    通过访问tixmlement TiXmlElement& (使用A 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")));
    

    相反,它将调用最后一个版本。另一个解决方法是进行常量转换:

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

    它将调用第一个版本。至于为什么它只发生在调试中…我记得TiXML有一个选项可以禁用STL。可能在释放模式下,您禁用了它(因此过载 std::string ,但在调试模式下,您忘记了?