2012-06-16 4 views
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(); 

    } 


}; 
+1

Да, это нормально – skirkpatrick

+0

Почему бы не выполнять такие функции, как 'const map & getFollowers() const', поэтому я могу получить доступ к данным, но не изменять их. Это гораздо удобнее, потому что итератор не дает мне полного контроля. Кроме того, для многих алгоритмов также необходим итератор. Поэтому я предлагаю вам не использовать такую ​​инкапсуляцию – Spo1ler

+0

@MatthieuM. благодаря – Spo1ler

ответ

2

Там в nothong неправильно с вашим подходом, за исключением того, что вы можете добавить константные методы доступа также, например, противник

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

Кроме того, вы хотите добавьте также итераторы end().

Что касается инкапсуляции, вы инкапсулируете карту, но ваши клиенты подвергаются воздействию map<string, bool>::iterator. Есть очень интересная статья о скрытии этих зависимостей here. Это отнюдь не тривиально, но это все равно стоит рассмотреть.

1

Да и нет.

Инкапсуляция имеет несколько значений.

  • В своей более легкой форме, то это означает, что класс имеет полный контроль над инкапсулированными членами, которые могут быть в данном случае (если вы возвратили const_iterator)
  • В своей тяжелой форме, это означает, что класс детали реализации не просочиться во внешнее слово, которое не дела здесь

Таким образом, вы не позволить другим получить контроль над внутренними (хорошим), но вы по-прежнему подвергать детали реализации, разбивая клиент, если вы когда-либо меняете то, как followers или following выполнен под крышками.

Возможное решение ввести циклическую конструкцию (например, Еогеасп):

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 один.

1

Я думаю, что могут возникнуть проблемы с дизайном, если вы рассмотрите этот вопрос дальше. Кажется, вы сохраните много контейнеров в этой настройке и установите последователь/следующий bool, чтобы указать, является ли условие истинным. Вернемся к этому через минуту.

Передача назад итератора может быть очень опасной, если контейнер управляется другим способом до/во время использования.Поэтому для вашего вопроса я бы подумал о передаче ссылки на контейнер, который нужно анализировать/манипулировать, и если используется многопоточность (в эти многоядерные дни мы должны всегда думать об этом) использовать мьютекс, чтобы сделать контейнерную нить безопасной или active object дизайна и простой реализации безопасной очереди.

Для этой настройки может быть лучше рассмотреть дизайн матричного типа, если у вас есть закрытая группа пользователей, или если у вас есть много-много ситуаций, то, возможно, рассмотрите что-то вроде boost multi index. Это может обеспечить более прозрачный дизайн.

Смежные вопросы