本文介绍了朋友类对象可以在派生类对象上访问基类私有成员吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很惊讶下面的代码编译。

I'm surprised that the code below compiles.

似乎与(公共继承的)基类成为朋友的类可以访问基类的成员提供了派生类的实例。

It seems that a class befriended to the (publicly inherited) base class can access a member of the base class provided an instance of the derived class.

如果继承更改为 private ,则编译失败。

If the inheritance is changed to private then compilation fails.

简而言之, d.b_var 如何在 F :: func(D& d)中有效?

#include <iostream>
#include <string>
using namespace std;

class B{
    int b_var;
    friend class F;
};

class D: public B{
    int d_var;
};

class F{
    public:
        void func(D &d){
            d.b_var = 5;
        }
};

int main()
{
    cout<<"fine";
}


推荐答案

<$ c $的对象c> D类由2个独立部分组成:

Object of class D is composed of 2 separate parts :

part containing members of B
part containing members of D

这就是为什么对象切片的概念在我们这样做时有效:

That why the concept of object slicing works when we do:

D objD;
B objB = objD;

现在我们可以从D类对象内部访问,部分包含B 的成员,通过 objB 。编译器会记住或者可以区分 class D 中的两个部分。所以编译器知道通过什么访问什么。

Now we can access from inside object of class D, the part containing members of B via objB. Compiler remembers or can distinguish between the two parts inside class D. So compiler know what is being accessed via what.

语句朋友类F; 在 B类只是告诉类F 的成员函数可以访问 private,protected和public B类成员。也就是说,对于类F的成员函数 class B 的所有成员都是 public 。

The statement friend class F; inside class B simply tells that member functions of class F can accesses the private, protected and public members of class B. That is, for member functions of class F all the members of class B are public.

实际上,在每个课程中,有三个部分可以访问:

Actually, inside every class there are three sections w.r.t accessibility:

public
protected
private

所以当我们声明一些 B级:

class B
{
    public:
        int a;
    protected:
        int b;
    public:
        int c;
};

然后在类 B 如上所示。

现在我们声明一些类F 成为的朋友 B类:

Now when we declare some class F to be a friend of class B:

class B
{
    friend class F;
    private:
        int a;
    protected:
        int b;
    public:
        int c;
};

然后编译器按如下方式创建部分:

then the compiler creates the sections as follows:

class B
{
    friend class F;
    private:
        int a;
    protected:
        int b;
    public:
        int c;
        //int a;  only for member functions of class F
        //int b;  only for member functions of class F
};

请注意 int a; 和 int b; 现在公开成员函数 class F 。

Note that int a; and int b; are now public for member functions of class F.

现在当 D类从< c>公开从< class B 然后 class B 的 public 部分变为 public class D 的部分。类似地, class B 的 protected 部分变为 protected 部分 D类。因此,可以通过 class D <的对象访问 class B 的 public 部分/ code>。因为 B :: a; 和 B :: b; 在的公共部分类F 的成员函数,因此 B :: a 和 B :: b 可以可以通过 class D 的对象访问。另请注意,虽然在派生后 int a; 和 int b; 成为类D的成员,仍然是编译器能够区分它们并认为它们是B类的部分。

Now when class D is derived publicly from class B then the public section of class B becomes public section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, the public section part of class B can be accessed via object of class D. And since B::a; and B::b; are in public section for members functions of class F, therefore B::a and B::b can be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B.

现在当 class D 派生私有来自 class B 然后 class B 的 public 部分变为 private 部分 D类。类似地, class B 的 protected 部分成为 class D 。因此,现在 class B 内的 public 部分无法通过 D类。回想一下,在 B类, B :: a; 和 B :: b; 最初是公共部分的类F 的成员函数,但在 private 派生后,成员 B类即 B :: a 和 B :: b 现在位于 class D 的私有部分。因此, B :: a 和 B :: b 无法通过 D类。另请注意,虽然在派生后 int a; 和 int b; 成为类D的成员,仍然编译器能够区分它们并将它们视为B类的部分。推导后, B类的某些成员的可访问性和规则已经改变。

Now when class D is derived privately from class B then the public section of class B becomes private section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, now the public section part inside of class B cannot be accessed via object of class D. Recall that in class B, B::a; and B::b; are originally in public section for members functions of class F but after private derivation, the members of class B i.e B::a and B::b are now in private section of class D. Therefore, B::a and B::b cannot be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B. After derivation the accessibility and rules of some members of class B have changed.

因为这个问题在某种程度上与效果有关公共,受保护和私有派生,因此为了完整性,请参阅:

Since this question somewhat relates to effect of public, protected and private derivation, therefore for completeness please see:Why can a derived class not access a protected member of its base class through a pointer to base?

这篇关于朋友类对象可以在派生类对象上访问基类私有成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 08:17