朋友类对象可以在派生类对象上访问基类私有成员吗? [英] Can a friend class object access base class private members on a derived class object?
问题描述
我很惊讶下面的代码编译。
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类
从< 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 $ c的受保护部分$ C>。因此,现在
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?
这篇关于朋友类对象可以在派生类对象上访问基类私有成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!