Оболочки для получения и установки для TiXmlElement * - PullRequest
1 голос
/ 17 декабря 2008

Я переписываю проект, чтобы он использовал геттеры и сеттеры для ссылки на TiXmlElement * Однако я быстро сталкиваюсь с проблемами, которые, похоже, связаны с режимом отладки:

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") выдает ошибку "CXX0039: Ошибка: символ неоднозначен" в VS2008 в режиме отладки.

Странная часть: IntelliSense обнаруживает метод FirstChildElement, и компилятор не выдает никаких ошибок.

Что еще более странно, так это то, что в режиме релиза просто не удается получить элемент диалога.

Что я делаю не так? Или, если вы успешно внедрили обертки для getter-сеттера для TiXmlElement *, дайте мне знать, как я могу!

Для полной справки вот выдержка из файла 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 Ответ

2 голосов
/ 17 декабря 2008

Убедитесь, что

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), но в режиме отладки вы забыли?

...