2012-04-05 130 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