1

C++ コードをできる限りカプセル化したいのですが、この方法でイテレータを返すことはできますか?

const map<string,bool>::iterator getFollowers() {

        return followers.begin();

    }

    const map<string,bool>::iterator getFollowing() {

        return following.begin();

    }

完全なコード:

#ifndef twitClient_twitUser_h
#define twitClient_twitUser_h

#include <map>
#include <iostream>
#include <string>

using namespace std;
class user {
    string username;
    map<string,bool> followers;
    map<string,bool> following;
    string name;


public:

    user(string username):username(username) {
        followers [username] = false;
        following [username] = false;
    }

    bool removeFollower (string friendName);
    bool addFollower(string friendName);
    bool stopFollowing(string friendName);
    bool startFollowing(string friendName);

    const map<string,bool>::iterator getFollowers() {

        return followers.begin();

    }

    const map<string,bool>::iterator getFollowing() {

        return following.begin();

    }


};
4

3 に答える 3

2

const アクセスメソッドも追加したい場合を除いて、アプローチに問題はありません。

map<string,bool>::const_iterator getFollowers() const;

end()さらに、イテレータへのアクセスも追加します。

カプセル化に関しては、マップをカプセル化しますが、クライアントはmap<string, bool>::iterator. これらの依存関係を非表示にすることに関する非常に興味深い記事がここにあります。決して些細なことではありませんが、検討する価値はあります。

于 2012-06-16T17:02:23.257 に答える
1

はいといいえ。

カプセル化にはいくつかの意味があります。

  • より軽い形式では、クラスがカプセル化されたメンバーを完全に制御できることを意味しますconst_iterator
  • より重い形式では、クラス実装の詳細が外部ワードに漏れないことを意味しますが、ここではそうではありません

したがって、他の人が内部を制御できるようにすることはできませんが (良いことです)、実装の詳細を公開し、カバーの下で実装方法を変更しfollowersたり実装したりすると、クライアントを壊します。following

考えられる解決策は、ループ構造 (foreach など) を導入することです。

template <typename Pred>
void user::foreachFollower(Pred& p) const {
    for (auto const& f: followers) { p(f); }
}

<string, bool>マップを からに変更する必要がある場合<string, int>(代わりに数値をカウントするため)、いつでも関数を変更できるため、これはより柔軟です。

template <typename Pred>
void user::foreachFollower(Pred& p) const {
    for (std::pair<std::string, bool> const& f: followers) { p(f); }
}

あなたのクライアントが壊れないように。これらは、クライアントが a を処理できるかどうかを検出するための精巧なトリックでもありますが、std::pair<std::string, int>実装するのは (少し) 困難です。


別の注意として、イテレータを与えるだけbeginでは十分ではなく、イテレータも必要endです。

于 2012-06-16T17:09:17.667 に答える
1

この質問をさらに検討すると、設計上の問題が発生する可能性があると思います。このセットアップで多くのコンテナを保持し、条件が真であるかどうかを示すためにフォロワー/フォローイングブールを設定するようです。すぐにこれに戻ります。

コンテナーが使用前または使用中に別のメソッドから操作された場合、イテレーターを戻すことは非常に危険です。したがって、あなたの質問に対して、コンテナへの参照を渡して分析/操作することを考えます。マルチスレッドが使用されている場合(これらのマルチコアの時代には、常にこれについて考える必要があります)、ミューテックスを使用してコンテナをスレッドセーフまたはアクティブオブジェクトにします型の設計と単純なセーフ キューの実装です。

この設定では、クローズド グループのユーザーがいる場合、または多対多の状況の場合は、おそらくboost multi indexのようなものを検討することをお勧めします。これにより、より明確で拡張可能な設計が提供される場合があります。

于 2012-06-16T17:14:01.703 に答える