[英]Why a friend class member can access a private member of the class it is being friend to through an object of publicly inherited class?
正如我們所知,在派生類中private
成員是不可訪問的(不僅僅是私有的),而在派生類中可以直接訪問public
和protected
的成員。
friend
,則后者擁有對第一個成員的完全訪問權限。這是一個我試圖理解但徒勞的例子:
class A
{
public:
int pub;
private:
int priv;
protected:
int prot;
friend class D;
};
class B : public A // public inheritance
{
int b = 0;
};
class C : private A
{
int c = 0;
};
class D
{
public:
void foo(B);
void bar(C);
};
void D::foo(B b)
{
b.pub = 0;
b.prot = 0;
b.priv = 0; // why this works? although A::priv is inaccessible in derived classes because it is private in base class?
// b.b = 0; // error. ok because b is private
}
void D::bar(C c)
{
// c.pub = 0; // error ok
// c.prot = 0; // error ok
// c.priv = 0; // error ok
// c.c = 0; // error. ok because c is private
}
D::foo
可以通過 object 從繼承自基A
的public
ly 訪問A
的私有成員,盡管我們知道private
在派生類中是不可訪問的? 那么為什么b.priv = 0;
作品? 我們知道friendship
既不是傳遞的,也不是繼承的? class D
是class A
的朋友,它可以完全訪問其公共、受保護和私人成員。 class B
public
ly inherit class A
, that means, class D
has access 1) to base class of class B
. 因此,使用class B
的 object 訪問class A
的priv
成員在class D
中是允許的。
Read below part of answer only if you are thinking that access of pub
, prot
and priv
, in D::bar(C)
function of friend class D
, is giving error because class A
is private
ly inherited by class C
.
在class C
的情況下,它private
繼承class A
。 As you have pointed out that the statements c.pub
, c.prot
and c.priv
of D::bar(C)
function are giving error. 是因為class C
繼承class A
private
的。
如果我取消注釋並編譯,我在D::bar(C)
function 中遇到的錯誤是:
p.cpp:44:5: error: cannot cast 'C' to its private base class 'A'
c.pub = 0;
^
p.cpp:21:11: note: declared private here
class C : private A
^~~~~~~~~
p.cpp:44:7: error: 'pub' is a private member of 'A'
c.pub = 0;
^
p.cpp:21:11: note: constrained by private inheritance here
class C : private A
^~~~~~~~~
p.cpp:8:12: note: member is declared here
int pub;
prot
和priv
成員也有同樣的錯誤。
這些錯誤是由於class A
的private
inheritance 引起的,與朋友class D
無關。 嘗試在朋友class D
之外以類似的方式訪問它,你會得到同樣的錯誤。
使用 C 樣式轉換,您可以將派生的 class 轉換為私有基礎 class ,如下所示:
void D::bar(C c)
{
((A*)&c)->pub = 0;
((A*)&c)->prot = 0;
((A*)&c)->priv = 0;
//c.c = 0; // error. ok because c is private
}
With this now you can access class C
private
ly inherit base class ( class A
) private members in its friend class class D
. Note that priv
member access using C style cast in D::bar(C)
function is working fine only because class D
is friend of class A
. 如果您嘗試使用 C 樣式轉換訪問派生 class 中的private
繼承基 class 的私有成員,則不允許:
class C : private A {
int c = 0;
public:
void Cfoo();
};
void C::Cfoo() {
((A*)this)->pub = 100;
((A*)this)->priv = 100; // error: 'priv' is a private member of 'A'
}
1)。 引用這個答案:
讓我們考慮一個 class Base
和一個繼承自Base
的 class Child
。
public
的,那么知道Base
和Child
的所有東西也都知道Child
繼承自Base
。protected
,則只有Child
及其子級知道它們從Base
繼承。private
的,那么除了Child
之外沒有人知道 inheritance。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.