2012-04-05 87 views
7

我有以下查詢;繼承和友誼訪問。 C++

classB inherits from classA 
classC is friend of classB 

這是否意味着classC應該能夠訪問classA的protected成員?由於classB從classA繼承了此類,因此classC可以訪問類classB中的所有內容?

回答

6

這意味着classC應該能夠訪問的classB保護classA子對象的一部分。應該能夠從classA本身訪問任何非公開的。

例如:

class C; 

class A 
{ 
protected: 
    int i; 
}; 

class B: 
    public A 
{ 
    friend class C; 
}; 

class C 
{ 
public: 
    void foo(A& a, B& b) 
    { 
    // a.i = 3; // not allowed 
    b.i = 3; // allowed, accesses the `i` of the `A` subobject of `B` 
    } 
}; 
+0

這是原始問題的更好答案。 – 2012-04-05 21:08:14

+0

@KerrekSB:謝謝。 – celtschk 2012-04-05 21:15:25

8

[我原來的答覆是無稽之談。爲此道歉。謝謝@celtschk指出了這一點,並提供更好的答案。]

如果CB的朋友,它可以訪問所有B的成員,私人,市民是否,或受保護的,而且包括訪問(public和protected)成員是基類子對象的一部分:

struct A { protected: int a; }; 
struct B : A { private: int b; friend struct C; } 

struct C 
{ 
    B x; 
    A w; 

    void f() 
    { 
     x.a = 1; // fine 
     x.b = 2; // fine 

     // w.a = 0; /* Error, #1 */ 
    } 

    friend struct D; // see below 
}; 

但是,友誼既不是傳遞還是繼承:CB的朋友,但不是A(見#1)。另外,如果DC的好友,那麼D不會獲得任何C的友誼給B所提供的訪問權限,因此D不能訪問B的非公共成員。同樣,如果從Cstruct E : C繼承,然後E也沒有的B朋友自動:

struct D 
{ 
    B y; 
    void g() 
    { 
     // y.b = 3; /* Error! */ 
    } 
}; 

struct E : C 
{ 
    B z; 
    void h() 
    { 
     // y.b = 4; /* Error! */ 
    } 
} 

或許可以總結一下的事情在幾個點:

  • 派生類訪問給每個基類的所有公共和受保護的成員。

  • 一個類的一個朋友有權訪問對訪問它(即不包括專用基站成員的所有成員)該類別的所有成員。

  • 友誼是不能繼承:如果一個類有一個朋友,友誼並不適用於任何其基類的也沒有任何派生類的。

  • 一個朋友的朋友是不是朋友。

+0

它也可以訪問'B'的'A'子對象的保護成員。它不能訪問任意'A'對象的受保護成員(但都不能'B')。 – celtschk 2012-04-05 20:51:41

+0

@celtschk:我認爲我的回答是完全錯誤的。我需要修改它。 – 2012-04-05 20:57:01

+0

它仍然沒有完全正確的:它當然只能訪問'A'子對象這'B'本身可以訪問這些成員。正如所寫的,它也應該可以訪問'A'的私人成員。 – celtschk 2012-04-05 21:07:35