如果我有两个类继承如下:
class A
{
...
}
class B : public A
{
...
}
第三个类定义为朋友类A:
class C
{
friend class A;
}
我是否能够class B
A
的所有成员class C
访问class B
,就像我已经定义了{{1}}朋友类一样首先是什么?
答案 0 :(得分:11)
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
}
};
参考:“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
现在都可以访问{{1}}个{{1}}成员了灾害。
答案 1 :(得分:3)
出于某种原因,每个人都忘记了你可以访问来自友谊提供者的类的虚拟私人功能。
#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;
}
运行上面代码的输出是:
Parent
Child
它工作的原因很棘手,并且与指针的传递方式有关(查找vtable)。你要删除&#34;虚拟&#34;函数声明中的关键字,你将失去这种能力。
答案 2 :(得分:2)
引用标准,C ++ 11 11.3 / 10:
友谊既不是遗传也不是传递。
这意味着朋友的派生类和朋友的朋友都不会得到友谊的好处。
答案 3 :(得分:1)
上面添加了Masked Man的答案/代码的另一个例子我觉得很有用:
bootstrap.js
答案 4 :(得分:0)
我认为这取决于。您可以从B的A部分(切片部分)访问。如果你已经定义了B自己的功能,我认为你不会。
答案 5 :(得分:0)
我不明白你要做什么,但B是A的超类。不是一个对象。在B和C之间没有任何继承关系
答案 6 :(得分:0)
此URL指出朋友类的子类不继承朋友关联:
这适用于两个“关联(主要类别自己和其他与主要类别相关的类别)” - 问题是针对后一种情况。
答案 7 :(得分:0)
不,您无法直接调用UIButton
类方法,但您可以通过指针访问它们。应修改C
类:
A
访问数据成员和静态数据也很简单