2017-01-25 6 views
0

コンポーネントAはポインタを含むセットを所有しているため、APIを設計してそのセットを返す予定です。 現在、他のコンポーネントはsetの内容のみを読み込み、何も変更するつもりはなく、APIから返されます。C++ STL List/Setのクエリを返すのは何ですか?

オプションは、次のとおり 1戻るセットのコピー 2戻りセットの基準 3.戻りセットの反復子の一対。 std:pair<ForwardIterator begin, ForwardIterator end>

問題は です。1.コピーするオーバーヘッドがあります。 2.これは内部セットを公開し、他のコンポーネントの変更を停止することはできません。 3.コンポーネントAがセットを変更した場合、イテレータは無効になりますか?

+1

APIのユーザーは何が必要ですか?彼らはそれがセットであることを知っているべきですか? – doctorlove

答えて

0

のは、あなたがこのことについて確信していると仮定しましょう当分の場合:受信クライアントコードが変更できないようにComponentAは 、 ポインタのセットを所有しているstd::set<Thing *>、そしてあなたはそれがそのセットを返すメソッドを持っているしたいのですが、それ。あなたは次のようなことをするかどうかは分かりません。

  1. セットのコピーを返します。
  2. セットへの参照を返します。
  3. セットの[begin()end()]の範囲を返します。

これらの操作は行わないでください。それぞれがあなた自身を特定した欠陥を持っています。 とにはのセットが返されないという追加の欠陥があります。イテレータ範囲を受信するクライアント コードは、それがを設定し、 がセットの定義特性を利用することができません区切ることを知ることができません。代わり

const方法からセットにconst参照を返す:

struct ComponentA 
{ 
    ... 
    ... 
    std:set<Thing *> const & get_set_of_things() const { 
     return things; 
    } 
private: 
    std::set<Thing *> things 
    ... 
}; 

これはの欠点除去 - クライアントコードが const参照して設定を変更することはできません - それ他の絡み目がない。

私は、それがあなたの質問に答える願っていが、私はそれはあなたの設計上の問題の終わりではないんです。

クライアントコードはget_set_of_things()によって返さ std:set<Thing *> const &を通じてthingsを変更することはできません。しかし、 私が変更できないものは、そのセットのメンバーです。単に ポインタThingです。私は確かにそれらのポインタは何か気にしない - 0x1a04c20のようなメモリアドレス - と私はの変更に興味がありません。しかし、何も は、それらのポインタ が指しているThingsのいずれかを修正するのをやめさせています。

ComponentA ca; 
... 
auto const & things = ca.get_set_of_things; 
Thing * pthing = *things.begin(); 
thing->modify(); 
... 

これはcaによって制御さThingsの一つ修正 - あなたがないようにしたい ものです。あなたはComponentAオブジェクトからセットを返す

ただし、限り、あなたは彼らにThing * -pointersを与えているように、オブジェクトによって制御さ Thingsの変更からクライアントを防ぐことはできません。

さてあなたはconst ポインタのセットにthingsを変更することで、この脅威をブロックすることができます:

struct ComponentA 
{ 
    ... 
    ... 
    std:set<Thing const *> const & get_set_of_things() const { 
     return things; 
    } 
private: 
    std::set<Thing const *> things 
    ... 
}; 

しかし、その変化の放射性降下物が今ComponentA自体Thingsを変更することはできませんということですthingsによって制御されます。あなたはそれで暮らすことができますか?

そして、これはあなたのComponentAはポインタのセットを制御する情報で をトリガしているいくつかの派手なデザインのアラームのちょうど最初のものです。 あなたのクラス定義をドラフトして、SOの姉妹サイトCode Reviewに のコメントを載せることをお勧めします。 コードが存在しない場合は特に のすべての可能性のある落とし穴を調べるのは、SOの範囲を超えています。

+0

マイク:あなたは完全に正しいです。戻り値はconst参照が最適です。そして、私は現在のセットホールド*ポインターで暮らすことができます。 – user7469511

関連する問題