2010-05-25 52 views
3

我有一個受保護的方法類Zig :: punt(),我只希望它可以訪問類「鱷梨」。在C++中,您通常會使用「friend Avocado」說明符來執行此操作,但這會導致所有其他變量可供「Avocado」類訪問;我不想要這個,因爲這打破了封裝。C++:有沒有辦法限制對某些類的某些方法的訪問,而不會暴露其他私有成員?

是我想不可能的,還是那裏已經存在一個晦澀的伎倆,我可以用來實現我想要的?或者可能有其他類設計模式可以實現相同的目標?

在此先感謝您的任何想法!

回答

4

這裏是一個醜陋但工作絕招:

class AvocadoFriender { 
protected: 
    virtual void punt() = 0; 
    friend class Avocado; 
} 

class Zig : public AvocadoFriender { 
    ... 
protected: 
    void punt(); 
} 

基本上你添加一個公開的接口只有一部分mixin類,你想要鱷梨。我們利用這樣一個事實,即通過繼承一個與鱷梨友好相處的類,除了最初暴露的內容之外,您不會再暴露任何東西。

0

您可以添加一個代理齊格類

class Foo 
{ 
    private: 
     int m_x, m_y; 
    public: 
     class Bar 
     { 
      friend class Baz; 
      int& x(Foo& blubb) 
      { 
       return blubb.m_x; 
      } 
     }; 
     friend class Bar; 
}; 

class Baz 
{ 
    public: 
     void grml(Foo& f) 
     { 
      Foo::Bar b; 
      // Yes, this looks awful 
      b.x(f) = 42; 
     } 
}; 

void z() 
{ 
    Foo f; 
    Baz b; 
    b.grml(f); 
} 
+3

如果您使用原始問題中存在相同的名稱。 'Foo'和'Baz'不會比'Zig'和'Avocado'無意義。 – 2010-05-25 07:48:38

3

我個人喜歡Key模式。

class WannaBeFriend { /**/ }; 

class WannaBeFriendKey: boost::noncopyable 
{ 
    friend class WannaBeFriend; 
    WannaBeFriendKey() {} 
}; 

現在:

class LimitedAccess 
{ 
public: 
    Item& accessItem(const WannaBeFriendKey&) { return mItem; } 

private: 
    Item mItem; 
    Item mOtherItem; 
}; 

我真的很喜歡這個方案,因爲:

  • 你只需要向前聲明(如友誼)
  • 你沒有由友誼授予的完全訪問權限,而不是僅限於有限訪問權限,在類作者的全權控制下
  • 而且它是完全清楚什麼可以訪問和誰在一起,從而緩解調試
  • 這種訪問可以的WannaBeFriend被授予子類:它只需要暴露protected: static const WannaBeFriend& Key();(可能會或可能不適用)

而且當然,編譯器很可能會優化這個參考的傳遞,因爲它不起任何作用,所以它不會破壞設計,也不會增加不必要的臨時對象:)

相關問題