Har*_*rry 9 c++ inheritance access-control friend
如果我有两个类继承如下:
class A
{
...
}
class B : public A
{
...
}
Run Code Online (Sandbox Code Playgroud)
第三类定义为朋友类A:
class C
{
friend class A;
}
Run Code Online (Sandbox Code Playgroud)
我是否能够从class B
(也是类型的对象A
)所有成员访问,class C
就像我首先定义class B
了朋友类一样?
Mas*_*Man 12
friend
船既不是遗传也不是传递.它是两个班级之间严格的一对一关系.
class A {
friend class B;
int Aries;
};
class B {
friend class C;
int Taurus;
};
class C {
int Leo;
void Capricorn() {
A a;
a.Aries = 0; // this wont work, C is not a friend of A.
// friendship is not transitive
}
};
class D : public C {
void Gemini() {
B b;
b.Taurus = 0; // this wont work, D is not a friend of B.
// friendship is not inherited
}
};
class E : public B {
void Scorpio() {
C c;
c.Leo = 0; // this wont work either, friendship is not inherited
}
};
Run Code Online (Sandbox Code Playgroud)
参考:"C++编程语言"Bjarne Stroustrup
更多解释(我的):如果friend
船不是一个人,那将是封装的结束.需要注意的是B
类可以访问private
的成员A
仅当类声明A
声明B
为friend
.B
不能强制friend
船舶A
.
现在,如果友谊可以继承,那么有人只需要继承B
来访问私人成员A
,而没有A
任何预防措施.此外,允许friend
船舶传递将导致其他问题,因为现在B
可能有一个friend
C
,而反过来可能有一个friend
D
,一直到Z
.所有的B
,C
,D
,...,Z
现在可以访问A
的private
成员,这将是一场灾难.
由于某种原因,每个人都忘记了您可以访问从友谊给予者派生的类的虚拟私有函数。
#include <iostream>
class Friend;
class Parent
{
friend class Friend;
private:
virtual void nameYourself() { std::cout << "Parent" << std::endl; }
};
class Child : public Parent
{
private:
virtual void nameYourself() { std::cout << "Child" << std::endl; }
};
class Friend
{
public:
void foo(Parent *p) { p->nameYourself(); }
};
int main()
{
Parent p;
Child c;
Friend f;
f.foo(&p);
f.foo(&c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行上面代码的输出是:
Parent
Child
Run Code Online (Sandbox Code Playgroud)
它起作用的原因很棘手,并且与该指针的传递方式有关(查找虚函数表)。如果您从函数声明中删除“virtual”关键字,您将失去这种能力。