2012-06-16 95 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錯了你的方法,但你可能要添加const的接入方式也一樣,敵人例如

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

另外,你要也可以訪問end()迭代器。

關於封裝中,封裝的地圖,但你的客戶接觸到map<string, bool>::iterator。有一篇關於隱藏這些依賴項的非常有趣的文章here。這絕不是微不足道的,但仍值得考慮。

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

1

我想可能有一些設計問題,如果你進一步考慮這個問題。似乎你會保留這個設置中的許多容器,並設置一個跟隨者/跟隨布爾來陳述條件是否爲真。一分鐘後回到這裏。

如果容器由另一種方法在使用過程中前操縱/傳遞迴一個迭代器可以是非常危險的。因此,對於您的問題,我會考慮通過對容器的引用進行分析/操作,如果使用多線程(在這些多核心時期,我們需要總是考慮這一點),請使用互斥鎖使容器線程安全或active object類型設計和簡單的安全隊列實現。

對於此設置可能會更好,如果你有用戶的一個封閉的羣體,或者如果你有一個多對多的情況,那麼也許考慮類似boost multi index考慮矩陣式設計。這可能會提供更清晰的可擴展設計。

相關問題