2

特定のオブジェクトを名前とタイプとともに保存するためのマップ コンテナーがあります。

typedef std::map<std::string, std::pair<ObjType, ObjBase*> > ObjContainer;

ただし、コードの多くの部分で、次のような構造があります。

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (it->second.second) {
        it->second.second->setObj2Default();
        delete it->second.second;
        it->second.second = 0;
    }
}

明らかに、多くの「it->second.second」はあまり明確ではなく、保守できません。将来変更された場合、たとえば、もう 1 つのフィールドをサポートするために、すべてが壊れます。したがって、次のように、フィールドにアクセスする関数によってそれらを変更しようとしています。

ObjBase*& getObjPtr(ObjContainer::iterator it) {
    return it->second.second;
}

同様に、getObjName および getObjType も機能します。

また、イテレータがこれらのフィールドを返すようにするとより明確になることも示唆されました。

 it.objPtr();
 it.objName();
 it.objType();

しかし、それらの機能を持たせるために STL イテレータを継承するべきではないと思いますよね? マップのラッパーを作成し、それらの関数を持つ独自のイテレータを用意する以外に、それを行う方法はありません。

では、最も適切な選択肢は何でしょうか? 私が見ていないこの問題を解決する他の方法はありますか?

4

4 に答える 4

4

最大の問題が保守性である場合、std::pair を、ObjType と ObjBase* を 1 つにラップするカスタム クラス/構造体に置き換えます。

  • ミックスに新しいフィールドを簡単に追加できます
  • 構造体フィールド ObjType および ObjPair に簡単にアクセスできます
  • ObjType と ObjPair を処理するクラスのゲッター/セッター/その他の関数を簡単に作成できます。
于 2012-04-03T22:10:46.707 に答える
2

ポインター (または参照) のローカル コピーを作成するだけです。とにかく最適化されるでしょう。

ObjContainer::iterator const it = mObjContainer.find(name);
if (it != mObjContainer.end())
{
    ObjBase * & p = it->second.second;
    if (p) { p->foo(); delete p; p = NULL; }
}
于 2012-04-03T22:08:57.180 に答える
0

まず、そこで ObjType が必須かどうかを自問します。目的が、ペアの 2 番目の ObjBase* パラメーターによって実際に指されているクラスの種類を確認することだけである場合は、ペアを使用して削除しますdynamic_cast

typedef std::map<std::string, ObjBase*> ObjContainer;

second.secondコードではこれ以上は必要ありません:

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (it->second) {
        it->second->setObj2Default();
        delete it->second;
        it->second = NULL;
    }
}

そして、オブジェクトの実際のタイプをテストする必要がある場合:

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (ChildObj* p_Child = dynamic_cast<ChildObj*>(it->second)) {
        // Work on p_Child...
    }
}
于 2012-04-03T22:35:37.457 に答える
0

参照を使用して構文を簡素化します。

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    std::pair<ObjType, ObjBase*> & ref = it->second;
    if (ref.second) { // ...
于 2012-04-03T22:09:31.247 に答える