2016-12-29 14 views
1

深くネストされたプライベートデータを特徴とする以下のクラス定義を検討してください。深くネストされたプライベートデータのためのC++/STLパブリックイテレータ

template <typename T, typename U, typename V> 
class NestedData { 
private: 
    typedef std::vector<V> L3; 
    typedef std::map<U, L3> L2; 
    typedef std::map<T, L2> L1; 
    L1 inner_data; 
}; 

パブリックインターフェイスを追加して、3つのレベルのそれぞれを反復処理したいとします。この場合

L1::const_iterator begin() const { return inner_data.begin(); } 
L1::const_iterator end() const { return inner_data.end(); } 

:それは、私たちは以下のメソッドを追加することができますタイプUとTの関連する値を知って、私たちはクライアントがタイプVの各値を反復3つのネストされたループを構築できるようにしたいですイテレータからの結果はペアになり、右側はL2型を参照します。参照はconstですが、std :: map型の完全なAPIを公開しています。これはパブリックインターフェイスには望ましくありません。よりクリーンなソリューションは、L2を反復することを可能にするラッパーのみを提供します。しかし、私はSTLコンテナのこの種のカプセル化の標準的な慣用句を見ていないし、最高の場合でも、ソリューションの実装は高度なコードの膨張を引き起こすようです。

この問題の一般的な解決方法は、一般的なC++規約ではうまくいくでしょうか?

+0

あなたのデータ構造を少し入れ子にして再構築したいのではないかと思っています... –

答えて

2

マップ自体をconstゲッターから公開するだけです。イテレータを公開すると、ユーザーは基になるデータ型にバインドされますが、そのデータ型は壊れています。たとえば、findを使用できないなど、利点はありません。

インナーマップが完全に実装の詳細になるようにクラスを再設計でき、クライアントがイテレーターとセッターを削除して意味のある関数を公開するよりも、クライアントがそれを見る必要はありません。

+0

+1また、const refを使ってマップを公開することで、クライアントがたとえあなたのデータ構造が変更されたとしても、コードを繰り返す必要はないはずです。 – RyanP

+0

'map'のAPI全体、あるいは' map'があるという詳細さえも公開されています。私は適切なカプセル化を達成する方法を探しています。 – epl

+0

マップイテレータを公開することによって、マップ自体を公開しています。あなたはそれを見ない? – SergeyA

0

私は反復の際にT、U、V値を提供するカスタムイテレータを作成します。これにより、ユーザーはデータの実装の詳細から完全に隔離されます。ネストされた型ロジックが本当に必要な場合。次に、最後のイテレーターをリストに戻すアダプター・オブジェクトを戻したカスタム・イテレーターを使用します。

関連する問題