C++編程基礎(chǔ)入門:友元接口

字號(hào):

限制你的友元類數(shù)量
    也許你遇到過這樣的情況:
    在一個(gè)類有一組策略,而且這組策略的實(shí)現(xiàn)都需要訪問A的一些成員,而且這些成員并不希望被其它類所訪問。
    一般這些成員被期望設(shè)置為保護(hù)或者私有的,并且這組策略被當(dāng)作這個(gè)類A的友元類。如:
    Code
    class Strategy1;
    class Strategy2;
    class Strategy3;
    class A
    {
    public:
    friend class Strategy1;
    friend class Strategy2;
    friend class Strategy3;
    private:
    void _foo();
    int _bar;
    };
    現(xiàn)在,假如你需要添加新的策略Strategy4為了維持這種微妙的關(guān)系,你需要把Strategy4添加為類A的新的友元類。
    隨著策略的增加,這個(gè)過程不斷擴(kuò)展A的友元類,最終你恐怕不會(huì)喜歡你看到的代碼。并且由于每次增加策略都需要使得依賴A的代碼重新編譯,這里一定有什么不妥之處。
    我想到一種解決方法,可以讓你的代碼看上去不算太混亂。
    首先,既然這組策略以相似的情況出現(xiàn)在A的周圍,那么它們可能有相似之處。比如它們可能需要訪問A的同一部分成員。
    那么假如通過一個(gè)代理類來訪問這些成員,那么這組策略就不必都是A的友元,只要這個(gè)代理是A的友元即可。
    這個(gè)代理我稱之為友元接口。
    Code
    class IFriendA_Strategy;
    class A
    {
    public:
    friend class IFriendA_Strategy;
    private:
    void _foo();
    int _foo2(int p) const;
    int _bar;
    };
    class IFriendA_Strategy
    {
    protected:
    typedef IFriendA_Strategy Friend; // 統(tǒng)一友元接口的訪問方式
    // 想必這組函數(shù)的實(shí)現(xiàn)不必給出了吧來源:
    static void _foo(A& rA);
    static int _foo2(const A& rA, int p);
    static int get_bar(const A& rA);
    static void set_bar(const A& rA, int value);
    };
    class Strategy1 : protected IFriendA_Strategy
    {
    public:
    void x(A &ra, int p)
    {
    // 于是你可以訪問了
    Friend::_foo(ra);
    int f = Friend::_foo2(ra, p);
    Friend::set_bar(ra, Friend::get_bar(ra) + f);
    }
    };
    如此一來,既完成了友元關(guān)系,又減少了依賴關(guān)系。
    缺點(diǎn)在于代碼不具備防御性,非授權(quán)類可以輕易的獲得訪問A保護(hù)成員的能力。只需要從友元接口繼承即可。
    這里再進(jìn)一步可以看到,如果類A有多組不同方面的策略,這些策略需要訪問A的成員的不同子集,那么它們可以獨(dú)立的歸到各自的友元接口上,互不相干。