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
无关。在friendclass 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的实例却不能?我想这与遗传类型有关。你能解释一下吗?非常感谢。