2011-10-06 82 views
3

當編碼被緊緊功能耦合類,但如果你想有一個簡單的界面,在世界其他地區,這將是整齊的,如果我可以做這樣的事情:允許C++類訪問其他類的一些「內部」成員,但不是私有的?

class log 
{ 
private: 
    log_context& cont; 
public: 
    create_log_section(std::string name) 
    { 
    cont.create_log_section(name);// this is fine! It's "internal" 
    cont.this_is_private();  // doesn't compile. Don't want anyone touching my privates! 
    } 
}; 

class log_context 
{ 
internal: 
    void create_log_section(std::string name); 
private: 
    void this_is_private(); 
internal friend log;    // Wow, possible? 
} 

現在,這將允許日誌訪問相關部分的背景,但不是私人部分。程序的其餘部分應該使用日誌來添加任何上下文。它也可以在日誌之間傳遞強類型log_contexts,而不需要任何額外的功率。我意識到這個特殊的解決方案是不可能的,但是如果有的話,還有哪些常見的解決方案呢?

回答

7

您可以使用一個內部類這樣做

class log_context 
{ 
    class internal 
    { 
     friend log; 

     static void create_log_section(log_context & context, std::string name) 
     { 
      context.create_log_section(name); 
     } 
    } 

    private: 
     void create_log_section(std::string name); 
     void this_is_private(); 
} 

class log 
{ 
    private: 

    log_context& cont; 

    public: 

    void create_log_section(std::string name) 
    { 
     log_context::internal::create_log_section(cont, name);// this is fine! It's "internal" 
    } 
}; 

內部,因爲只有私人靜態功能,只有它的朋友可以訪問它

4

友誼不交叉繼承邊界。如果log_context要繼承一些log_context_basethis_is_private將成爲log_context_base的一部分,則作爲log的朋友的log_context將不允許log訪問this_is_private

class log_context_base 
{ 
protected: 
    void this_is_private(); 
} 

class log_context : protected log_context_base 
{ 
internal: 
    void create_log_section(std::string name); 
    friend log; 
} 

注意我,因爲我不希望log_context使用過這裏的保護繼承使用log_context_base*進行訪問。

這樣一來,你會得到你想要的東西,而無需新的關鍵字添加到語言;)

0

一般的解決方案是製作一個full的朋友,並且由於它在你的控制之下,所以只要確保它只觸及它應該接觸的東西即可。

我前段時間介紹的另一個解決方案是使用Key

class Key { friend class log; Key() {} ~Key() }; 

class log_context { 
public: 
    void create_log_section(std::string name, Key const&); 
}; 

唯一關鍵的朋友可以創建它的一個實例,因此,只有他們(或他們所傳遞一個參考關鍵)可以訪問「限制」的方法。

我很喜歡這種方法來記錄有限訪問。

相關問題