2012-03-26 42 views
5

給出的樣本代碼:朋友是否看到基類?

class Base { 
public: 
    bool pub; 
protected: 
    bool prot; 
}; 

class Derived : private Base { 
    friend class MyFriend; 
}; 

class MyFriend { 
    Derived _derived; 

    void test() { 
    // Does standard provide me access to _derived.pub and _derived.prot? 
    cout << "Am I allowed access to this: " << _derived.pub 
     << " and this: " << _derived.prot; 
    } 
}; 

是否是一個朋友給我的所有訪問,就好像我是在類中的成員函數我會得到到我的朋友嗎?換句話說,我可以得到自從我是朋友以來私下繼承的基類的受保護和公共成員嗎?

+5

看到,因爲你已經去麻煩寫上去的示例代碼,你試過*編譯它*?這種答案會很快暴露在警告/缺乏之中。 – ssube 2012-03-26 19:51:42

+2

@peachykeen:編譯器接受什麼,標準說什麼通常是不同的東西。另外,從理論上講,示例代碼無法捕捉到的細微之處。 – 2012-03-26 20:13:54

+0

@AdrianMcCarthy的確如此。但是,許多編譯器會在使用非標準功能時發出警告,如果違反標準和編譯器的實現,您將得到一個簡短而甜蜜的答案。雖然不是萬無一失,但嘗試並不會傷害。 – ssube 2012-03-27 13:43:06

回答

6

結合大衛·羅德里格斯的答案 - dribeas和Luchian格里戈雷:

是,在問題中所說的工作,但是,正如大衛指出,受保護的成員不能直接通過基類訪問。您只有在通過Derived訪問受保護的成員時才能訪問,當您通過Base訪問時,您無權訪問相同的成員。

換句話說,基地的受保護成員被視爲派生的私人成員,因此朋友可以看到他們,但是,如果您投給基類,則沒有朋友關係,因此受保護的成員不再可訪問。

這裏是明確的區別的例子:

class MyFriend { 
    Derived _derived; 

    void test() { 
    bool thisWorks = _derived.pub; 
    bool thisAlsoWorks = _derived.prot; 

    Base &castToBase = _derived; 

    bool onlyPublicAccessNow = castToBase.pub; 
    // Compiler error on next expression only. 
    // test.cpp:13: error: `bool Base::prot' is protected 
    bool noAccessToProtected = castToBase.prot; 
    } 
}; 
2

朋友聲明將使得MyFriend有權訪問繼承關係(即對世界其他地方爲private),但不會授予其訪問受保護基礎成員的權限,僅限於公共接口。

void MyFriend::test() { 
    Derived d; 
    Base & b = d;   // Allowed, MyFriend has access to the relationship 
    b.prot = false;  // Not allowed, it does not have access to the base 
} 
1

是的,因爲Base的成員也Derived的成員(因爲他們沒有privateBase)。