1

ゲッターとセッターを使用して 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* のゲッター セッター ラッパーの実装に成功した場合は、私にもその方法を教えてください!.

完全なリファレンスとして、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 を調べていませんが、そのような落とし穴に注意してください。

あいまいな呼び出しの理由は次のとおりです。

FirstChildElement1 つの引数を取る 3 つのオーバーロードがあります。

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

1 番目と 3 番目のオーバーロードの間にはあいまいさがあります。簡単な修正は行うことです

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

代わりに、最後のバージョンを呼び出します。もう 1 つの修正方法は、const_cast です。

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

これは最初のバージョンを呼び出します。なぜDEBUGでのみ発生するのか... TiXMLにはSTLの使用を無効にするオプションがあることを覚えています。おそらくリリースモードでは無効にしましたが(したがって、オーバーロードが を取得しstd::stringました)、デバッグモードでは忘れていましたか?

于 2008-12-17T12:04:16.183 に答える