2012-04-05 42 views
7

Tôi có truy vấn sau đây;Quyền thừa kế và quyền truy cập tình bạn. C++

classB inherits from classA 
classC is friend of classB 

Điều này không có nghĩa là classC có thể truy cập thành viên được bảo vệ của classA? Vì classB kế thừa từ classA, classC có thể truy cập mọi thứ trong class classB?

Trả lời

6

Nó có nghĩa là classC sẽ có thể truy cập được bảo vệ một phần classA subobject của classB. Cần không phải mới có thể truy cập mọi thứ không công khai từ chính số classA.

Ví dụ:

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

Đây là câu trả lời hay hơn cho câu hỏi gốc. –

+0

@KerrekSB: Cảm ơn bạn. – celtschk

8

[Câu trả lời ban đầu của tôi là vô nghĩa. Xin lỗi vì điều đó. Cảm ơn bạn @celtschk đã chỉ ra rằng và cung cấp câu trả lời tốt hơn.]

Nếu C là một người bạn của B, nó có thể truy cập tất cả các thành viên B 's, cho dù tư nhân, công cộng, hoặc được bảo vệ, và bao gồm các truy cập các thành viên (công cộng và bảo vệ) là một phần của một subobject cơ sở:

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 
}; 

Tuy nhiên, tình bạn không phải là bắc cầu cũng không được thừa hưởng: C là một người bạn của B, nhưng không phải của A (xem # 1). Ngoài ra, nếu D là bạn của C thì D sẽ không nhận được bất kỳ quyền truy cập nào mà tình bạn của C gửi đến B, hãy D không thể truy cập vào các thành viên không công khai của B. Tương tự, nếu struct E : C thừa hưởng từ C, sau đó E cũng không phải là một người bạn của B tự động:

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

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

Có lẽ người ta có thể tóm tắt những gì đang xảy ra trong một vài điểm:

  • Một lớp học có nguồn gốc có quyền truy cập cho tất cả các thành viên công cộng và được bảo vệ của mỗi lớp cơ sở.

  • Một người bạn của một lớp học có quyền truy cập vào tất cả các thành viên của lớp đó có thể truy cập được (nghĩa là tất cả các thành viên không bao gồm thành viên cơ sở tư nhân).

  • Tình bạn không được thừa kế: Nếu một lớp có bạn, tình bạn đó không áp dụng cho bất kỳ lớp cơ sở nào của nó cũng như bất kỳ lớp học có nguồn gốc nào.

  • Một người bạn của một người bạn không phải là bạn.

+0

Nó cũng có thể truy cập vào các thành viên protected của '' A' subobject b' của. Nó không thể truy cập các thành viên được bảo vệ của các đối tượng 'A' tùy ý (nhưng không thể có' B'). – celtschk

+0

@celtschk: Tôi nghĩ câu trả lời của tôi hoàn toàn sai. Tôi cần phải sửa đổi nó. –

+0

Nó vẫn chưa hoàn toàn chính xác: Tất nhiên nó chỉ có thể truy cập những thành viên của 'A' subobject mà' B' chính nó có thể truy cập. Như đã viết, nó cũng nên có quyền truy cập vào các thành viên riêng của 'A'. – celtschk

Các vấn đề liên quan