[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.
Nguồn
2012-04-05 20:40:37
Đây là câu trả lời hay hơn cho câu hỏi gốc. –
@KerrekSB: Cảm ơn bạn. – celtschk