Я переписываю проект так, чтобы он использовал геттеры и сеттеры для ссылки на 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, и компилятор не выдает никаких ошибок.
Что еще более странно, так это то, что в режиме выпуска он просто не может получить элемент диалогов.
Что я делаю не так? Или, если вы успешно реализовали обертки-установщики геттеров для 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>
Буду очень признателен за обратную связь, так как я зашел в тупик :)





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