2012-06-16 2 views
1

나는 내 C++ 코드를 캡슐화 할 수 있기를 바랄 수있다.그런 방식으로 반복자를 반환 할 수 있습니까?

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

     return followers.begin(); 

    } 

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

     return following.begin(); 

    } 

전체 코드 : 당신이 너무 CONST 액세스 방법을 추가 할 수 있습니다 것을 제외하고

#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'와 같은 기능을 사용하지 않는 이유는 무엇입니까? iterator가 완전히 제어 할 수 없기 때문에 훨씬 더 편리합니다. 또한 많은 알고리즘에서 end iterator가 필요합니다. 그래서 나는 그러한 인 캡슐 레이션을 사용하지 말 것을 제안합니다. – Spo1ler

+0

@MatthieuM. 감사 – Spo1ler

답변

2

이, 당신의 접근 방식과 nothong 잘못된있다, 원수 예

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

게다가 당신이 원하는 end() 반복기에도 액세스 할 수 있습니다.

캡슐화와 관련하여지도를 캡슐화했지만 클라이언트는 map<string, bool>::iterator에 노출됩니다. 이러한 종속성을 숨기는 것에 대한 매우 흥미로운 기사가 ​​있습니다. here. 결코 사소한 것은 아니지만 고려할만한 가치가 있습니다.

1

예 아니요.

캡슐화에는 여러 가지 의미가 있습니다. 그것의 가벼운 형태에서

  • , 그것은 클래스가 무거운 형태에서
  • (당신이 const_iterator을 반환하는 경우) 여기 경우 될 수있는 캡슐화 된 멤버를 완벽하게 제어 할을 가지고 있다는 것을 의미, 그것은 클래스 있음을 의미 구현 세부 사항은 여기 안 경우 그래서

입니다 외부 단어에 누설하지 않습니다, 당신은 다른 사람은 (좋은) 당신의 내부 통제를 얻을하지 않습니다하지만 당신은 여전히 ​​경우 클라이언트를 깨고 구현 세부 사항을 노출 너는 이제까지 어떻게 바뀌는가 followers 또는 following은 커버하에 구현됩니다.

가능한 솔루션 (예 : foreach는 등) 루프 구조를 소개하는 것입니다 :

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

당신이 <string, int><string, bool>에서지도를 변경해야합니다 (대신 숫자를 계산하기 위해) 때문,보다 유연, 당신을 기능을 항상 바꿀 수 있습니다.

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이 조건이 true인지 여부를 설정하도록 설정합니다. 이것으로 잠깐.

컨테이너를 사용 전/사용 중에 다른 방법으로 조작하면 이터레이터를 되돌릴 수 있습니다.그래서 귀하의 질문에 대한 컨테이너에 대한 참조를 분석/조작 및 멀티 스레딩 (이러한 멀티 코어 시대에 우리는 항상 이것에 대해 생각해야합니다) 컨테이너 뮤텍스를 사용하여 컨테이너를 안전하게하거나 active object 유형을 사용하는 경우에 대해 생각할 것입니다 디자인 및 간단한 안전한 대기열 구현.

이 설정의 경우 닫힌 사용자 그룹이 있거나 많은 상황이 많은 경우 boost multi index과 같은 것으로 고려하면 매트릭스 유형 디자인을 고려하는 것이 좋습니다. 이것은 더욱 확장 가능한 디자인을 제공 할 수 있습니다.

관련 문제