簡體   English   中英

為什么朋友 class 成員可以通過公共繼承的 class 的 object 訪問其成為朋友的 class 的私人成員?

[英]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成員是不可訪問的(不僅僅是私有的),而在派生類中可以直接訪問publicprotected的成員。

  • 如果一個 class 將另一個 class 聲明為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 從繼承自基Apublic ly 訪問A的私有成員,盡管我們知道private在派生類中是不可訪問的? 那么為什么b.priv = 0; 作品? 我們知道friendship既不是傳遞的,也不是繼承的?

class Dclass 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 Apriv成員在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;

protpriv成員也有同樣的錯誤。

這些錯誤是由於class Aprivate 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

  • 如果 inheritance 是public的,那么知道BaseChild的所有東西也都知道Child繼承自Base
  • 如果 inheritance protected ,則只有Child及其子級知道它們從Base繼承。
  • 如果 inheritance 是private的,那么除了Child之外沒有人知道 inheritance。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM