2017-07-17 114 views
2

訪問另一個實例的保護成員在this answer問題「?共同基類中定義另一個對象爲什麼不是我的對象訪問保護成員」,一個可以讀取:不能從派生類型的範圍

您只能從您自己的基類實例訪問受保護的成員。

要麼我沒有正確地得到它或following MCVE (live on coliru)證明她錯了:

struct Base   { void f(); protected: int prot; }; 
struct Derived : Base { void g(); private: int priv; }; 

void Base::f() 
{ 
    Base b; 
    b.prot = prot; 
    (void) b; 
} 

void Derived::g() 
{ 
    { 
     Derived d; 
     (void) d.priv; 
    } 

    { 
     Derived& d = *this; 
     (void) d.priv; 
    } 

    { 
     Derived d; 
     (void) d.prot; // <-- access to other instance's protected member 
    } 

    { 
     Derived& d = *this; 
     (void) d.prot; 
    } 

    // --- 

    { 
     Base b; 
     (void) b.prot; // error: 'int Base::prot' is protected within this context 
    } 

    { 
     Base& b = *this; 
     (void) b.prot; // error: 'int Base::prot' is protected within this context 
    } 
} 

在兩個錯誤,我得到想知道的光:我爲什麼能訪問到另一個Derived實例的保護成員從Derived的範圍,但無法從相同範圍訪問另一個Base實例的受保護成員,而不管Derived是否從Base開始? TL;博士:在這種情況下,protectedprivate更「私人」嗎?

  • 請不要關閉這個問題作爲鏈接的問題的重複;
  • 更好的標題建議是受歡迎的。
+0

即使您*在範圍內查看對象*,訪問說明符的作用相同。你使用'Base'引用,這就是她寫的全部內容。 – StoryTeller

回答

2

[class.access.base]中的規則是:

當類N如果命名爲A構件m是在點- [R訪問[...]

  • m作爲成員的N受保護,並且R發生在類N的成員或朋友中,或在成員從N,其中m推導的P成員的類P的r是publicprivate,或者protected

有很多的在那裏字母。但基本上有兩個條件:

  1. R是在類的成員或朋友。這處理​​示例 - 我們在Derived的成員中,同時訪問Derived的受保護成員。
  2. R是派生類的成員,正在訪問的成員是派生類實例的成員。這處理了b.prot示例 - 我們處於派生類的成員中,但prot不是派生類的成員。

換句話說,Derived可以訪問Base的保護成員 - 但只有在它正在訪問自己的子對象的保護成員的情況。它不能訪問其他Base對象的受保護成員。當你認爲這個其他Base很容易成爲SomeOtherDerived時,這是有道理的,在這種情況下,這只是另一個與我們無關的對象,我們沒有特殊的訪問權限。

+0

這個答案證實了'protected'訪問說明符不像'private'和'public'那麼簡單! – YSC