如果我有两个继承类如下:
class A
{
...
}
class B : public A
{
...
}
第三类定义为朋友类A:
class C
{
friend class A;
}
我是否能够从class B
(也是 type 的对象A
)访问所有成员,class C
就好像我首先定义class B
了朋友类一样?
如果我有两个继承类如下:
class A
{
...
}
class B : public A
{
...
}
第三类定义为朋友类A:
class C
{
friend class A;
}
我是否能够从class B
(也是 type 的对象A
)访问所有成员,class C
就好像我首先定义class B
了朋友类一样?
friend
ship 既不是继承的也不是传递的。这是两个类之间严格的一对一关系。
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
ship 是可传递的会导致其他问题,因为 nowB
可以有一个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;
}
运行上述代码的输出是:
Parent
Child
它起作用的原因很棘手,并且与该指针的传递方式有关(查找 vtables)。如果您从函数声明中删除“virtual”关键字,您将失去此能力。
引用标准 C++11 11.3/10:
友谊既不是遗传的,也不是传递的。
这意味着派生类的朋友和朋友的朋友都不能获得友谊的好处。
在上面我发现有用的蒙面人答案/代码中添加了一个示例:
class B {
friend class F;
friend class E;
int Taurus;
};
class E : public B {
int Egg;
};
class F {
void Foo () {
B b;
b.Taurus = 4; //Works F is friend of B (of course)
E e;
e.Taurus = 6; // Works E is derived from B and F is friend of B
// Taurus is private member of B.
e.Egg = 5; // Does not work, F is friend of Base Class B but not
// E, so can't access members of the derived class
}
};
我认为这取决于。您将可以从 B 的 A 部分(切片部分)访问。如果你定义了 B 自己的函数,我想你不会。
我不明白您要做什么,但是 B 是 A 的超类。不是对象。B和C之间没有任何继承关系
此 URL 声明朋友类的子类不继承朋友关联:
这适用于两个“关联(主类自己的和与主类友好的其他类)”——这里的问题是后一种情况。
不,您不能C
直接调用类方法,但可以通过指针访问它们。A
类应该被修改:
class C
{
void method()
{
}
friend class A;
};
class A
{
protected:
constexpr static void (C::*f)() = &C::method;
};
class B : public A
{
B()
{
//C().method(); ← This wont work
(C().*f)(); // ← This works fine
}
};
访问数据成员和静态数据也很简单