Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么好友类成员可以通过公共继承类的对象访问其好友类的私有成员?_C++_Inheritance_Friend_Access Specifier - Fatal编程技术网

C++ 为什么好友类成员可以通过公共继承类的对象访问其好友类的私有成员?

C++ 为什么好友类成员可以通过公共继承类的对象访问其好友类的私有成员?,c++,inheritance,friend,access-specifier,C++,Inheritance,Friend,Access Specifier,正如我们所知,private成员在派生类中是不可访问的(不仅仅是private),而public和protected在派生类中是可直接访问的 如果一个类将另一个类声明为朋友,那么后者可以完全访问第一个类的成员 下面是一个我试图理解但徒劳的例子: class A { public: int pub; private: int priv; protected: int prot; friend class D; };

正如我们所知,
private
成员在派生类中是不可访问的(不仅仅是private),而
public
protected
在派生类中是可直接访问的

  • 如果一个类将另一个类声明为
    朋友
    ,那么后者可以完全访问第一个类的成员
下面是一个我试图理解但徒劳的例子:

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
    可以通过从基本
    A
    继承的
    public
    对象访问
    A
    的私有成员,尽管我们知道
    private
    在派生类中是不可访问的?那么为什么
    b.priv=0有效吗?我们知道友谊既不是传递的,也不是继承的

D类
是A类的朋友,它可以完全访问其公共、受保护和私人成员<代码>B类
公共
可以继承
A类
,这意味着
D类
可以访问
B类
的基类。因此,在
class D
中允许使用
class B
的对象访问
class A
priv
成员


只有当您认为好友类
D
函数中的
pub
prot
priv
访问
D::bar(C)
时,才能阅读下面的部分答案,因为
类A
类C
继承的
private

类别C
的情况下,它
私有
可以继承
类别A
。正如您所指出的,
D::bar(c)
函数的
c.pub
c.prot
c.priv
语句给出了错误。这是因为
C类
继承
A类
私有
ly

如果我取消注释并编译它们,我在
D::bar(C)
函数中遇到的错误是:

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
成员也有相同的错误

这些错误是由于
private
继承了
class A
与朋友
class D
无关。在friend
class D
之外尝试以类似的方式访问它,您将得到相同的错误

使用C样式转换可以如下所示:

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
}
现在,您可以访问
类C
私有
并继承其友元类
类D
中的基类(
类A
)私有成员。 请注意,
priv
使用C样式强制转换的
D::bar(C)
函数进行成员访问工作正常,这仅仅是因为
类D
类A
的朋友。 如果尝试使用C样式转换访问派生类中的
private
ly继承基类的私有成员,则不允许:

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) 。 引述答覆:

让我们考虑一个类<代码> Base<代码>和一个类<代码>子<代码>,继承自<代码> Base< /Cord>

  • 如果继承是
    public
    ,则知道
    Base
    的所有内容
    Child
    也知道
    Child
    继承自
    Base
  • 如果继承受
    保护
    ,则只有
    子继承及其子继承受保护
    意识到它们继承自
    Base
  • 如果继承是
    私有的
    ,则除了
    子继承之外,没有人知道
    遗产

“我们知道友谊既不是传递的,也不是继承的?”-你的例子没有违反这一点。只有
A
部分被访问。@StoryTeller UnslanderMonica:但是为什么D的成员函数中的B的实例甚至可以访问A的私有成员,而C的实例却不能?我想这与遗传类型有关。你能解释一下吗?非常感谢。