我能以这种方式返回迭代器吗?

时间:2012-06-16 16:57:39

标签: c++ iterator

我希望我的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();

    }


};

3 个答案:

答案 0 :(得分:2)

你的方法没有错,除了你可能想要添加const访问方法,例如

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

另外,您还希望添加对end()迭代器的访问权限。

关于封装,您封装了地图,但您的客户端被map<string, bool>::iterator公开。有一篇关于隐藏这些依赖项here的非常有趣的文章。这绝不是微不足道的,但仍值得考虑。

答案 1 :(得分:1)

是和否。

封装有几个含义。

  • 以较轻的形式表示该类可以完全控制封装成员,这可能就是这种情况(如果您返回了const_iterator
  • 在更重的形式中,这意味着类实现细节不会泄漏到外部单词中,这里

所以,你不要让其他人控制你的内部(好),但你仍然会暴露实施细节,如果你改变了followersfollowing的实施方式,你就会破坏客户。

一种可能的解决方案是引入循环结构(例如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); }
}

这样您的客户就不会受损。它们也是精心设计的技巧,用于检测客户端是否可以处理std::pair<std::string, int>,但它们(有点)难以实现。


另一方面,仅提供begin迭代器是不够的,它们还需要end个。

答案 2 :(得分:1)

如果您进一步考虑这个问题,我认为可能存在一些设计问题。似乎您将在此设置中保留许多容器并设置跟随者/后续bool以说明条件是否为真。一分钟后回到这一点。

如果在使用之前/期间使用其他方法操作容器,则传回迭代器可能非常危险。因此,对于您的问题,我会考虑传递对要分析/操作的容器的引用,如果使用多线程(在这些多核心日期我们需要始终考虑这一点)使用互斥锁来使容器线程安全或{{ 3}}类型设计和简单的安全队列实现。

对于此设置,如果您有一组封闭的用户,或者如果您有多对多的情况,那么可能最好考虑矩阵类型设计,然后可能会考虑类似active object的内容。这可以提供更清晰,更可扩展的设计。