/*
一个类A声明为一个类B的友元类之后,类A就可以任意访问类B的所有
成员(公有的、保护的和私有的)。但是,如果一个类D继承自类B,
类B中的友元关系并不会被继承,也就是说,类A是类B的友元但却不是
类B的派生类D的友元。即类A不可以访问类D的保护的和私有的成员。
在上面的代码中,被注释了的部分不能够通过编译,因为D不是A的友
元类,B的友元关系并没有被继承。而在A的Print函数成员中,参数为
基类B的const引用;而实参却可以是D类的对象,从而实现了在A类中
调用D类成员的目的。当然,你完全可以把A声明为D的友元类。对这种
机制的解释:首先,在A的Print函数中,通过B类对象调用其私有的虚
函数(b.Print();),由于A是B的友元,该调用是完全合法的。而在用
D对象调用A的Print函数时时,b.Print()调用动态绑定到了对D类对象
的函数版本的调用。这里,也说明了另外一个问题:类成员的访问控制
只是在编译时有效。
*/
#include <iostream>
using namespace std;
class B
{
friend class A;
private:
virtual void Print() {
std::cout << "B" << std::endl;
}
};
class D: public B
{
private:
virtual void Print() {
std::cout << "D" << std::endl;
}
};
class A
{
public:
A() {
B b;
std::cout << "A Constructor: ";
b.Print(); // ok
//D d;
//d.Print(); // error: 'virtual void D::Print() const' is private
}
void Print( B &b) {
std::cout << "A --> ";
b.Print();
}
};
int main()
{
A a;
B b;
D d;
a.Print(b);
a.Print(d);
return 0;
}