とりわけ、std::listを含むクラスがあります。このリストを公開したいのですが、構造とそれに含まれるデータが読み取り専用であり、イテレーターで使用できるようにする場合に限ります。
私がそれを「機能する」ATMにする方法は、リストのコピーを返すことです。これにより、クラスは「安全」になりますが、もちろん、呼び出し元がリストのコピーを変更して適切なデータを取得できないようにすることはできません。
もっと良い方法はありますか?
const std::list&
代わりに 返品してみませんか?
リスト自体を(まったく)公開する代わりに、const_iterator
sをその最初と最後に公開するだけです。これを行うためのヘルプを参照cbegin()
してくださいcend()
...
データメンバーを外界に公開することには依存関係の問題があります。
属性をより良いものに変更することを決定した場合(list
最後の手段のコンテナーであるため)、または新しい要件があるために、すべてのクライアントが影響を受けますが、それは悪いことです。
簡単な代替方法の1つは、typedef
:を提供することです。
typedef std::list<Foo>::const_iterator const_iterator;
クライアントがエイリアスを使用している場合は、コードを再コンパイルするだけです。
もう1つの方法は、実際のイテレータを埋め込む独自のイテレータクラス(それほど難しくはありません)を作成することです。
class const_iterator
{
public:
private:
typedef std::list<Foo>::const_iterator base_type;
base_type mBase;
};
すべての操作を実際のイテレーターに転送するだけで、クライアント(コンテナーを変更した場合は再コンパイルする必要があります)が誤ってエイリアスされていないタイプを使用することはありません。
次に、3番目のソリューションは最初のソリューションと似ていますが、型を抽象化する点が異なります...ただし(リストの場合)非常に非効率的であるため、あまりお勧めしません。イテレータはコピーするのが安価であるはずです。何でもしたいnew
。
const参照を返します:
const std::list<T>& getList() const;
または、定数イテレータを返すだけです。
std::list<T>::const_iterator getListBegin() const;
std::list<T>::const_iterator getListEnd() const;
class foo {
private:
typedef std::list<bar> bar_cont_t;
public:
typedef bar_const_t::const_iterator bar_const_iterator;
bar_const_iterator bar_begin() const {return bar_data_.begin();}
bar_const_iterator bar_end () const {return bar_data_.end ();}
// whatever else
private:
bar_cont_t bar_data_;
};