私が保守しているアプリケーションで、永続化されていたアイテムのタイプを除いてすべて同じことを行う6つの関数を持つ永続化クラスに出くわしました。これらのアイテムはすべて同じ基本クラスであり、テンプレート関数の候補です。
ただし、一度変換すると、いくつかの項目が含まれているはずなのに、関数が書き込まれているコンテナーにステップインされると、常に空になります(一時的なコピーが作成されますか?)。確かに、デバッガーでコンテナーを検査すると、コンテナーの項目はゼロです。また、書き込み関数は、ステータスの変更をクライアントに通知するイベントをトリガーしますが、そのスレッドがdequeからアイテムを抽出しようとすると、常に空になります。
基本クラスはCItemと呼ばれ、他のすべてのアイテムはそのアイテムの特殊です(CErrorItem
など)。それらはすべて、両端キュー(std::deque<std::tr1::shared_ptr<CItem>> m_items;
)およびディスクに永続化されます。アイテムは正しくディスクに書き込まれます。正しく処理されると、アイテムはdequeとdiskの両方から削除されます。
アイテムはコードで追加されますm_persistence.Add<CErrorItem>(errorItem);
アイテムのすべてのデータは単純な構造体(例ErrorItemInfo
)に格納され、アイテムはこれらの単純なデータストアをコンストラクターに取り込みます。U
以下のコードでで示されているのはこの構造体です。はT
派生CItem
です。
アイテムを追加する機能は次のとおりです。
template <typename T, typename U>
std::tr1::shared_ptr<T> CPersistenceManager::Add(const U& item)
{
std::tr1::shared_ptr<T> newItem = std::tr1::shared_ptr<T>(new T(item));
// .. a couple of lines calling helper functions to generated a unique timestamped filename
newItem->Write(filename); // this writes to disk and works.
m_items.push_back(newItem); // m_items is always empty
SetEvent(m_itemAddedEvent); // notify the client an item has been added.
return newItem;
}
最も簡単な解決策は、コードを特定の関数に戻すことです。おそらくそうしますが、将来これを回避できるように、なぜこれが発生するのかを理解したいと思います。