野百合也有春天

导航

友元类

#include "stdafx.h"
#include <iostream>

/*一个类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类对象
的函数版本的调用。这里,也说明了另外一个问题:类成员的访问控制
只是在编译时有效。*/

class B
{
	friend class A;
private:
	virtual void Print() const
	{
		std::cout<<"B"<<std::endl;
	}
};

class D : public B
{
	friend class A;
private:
	virtual void Print()
	{
		std::cout<<"D"<<std::endl;
	}
};

class A
{
public:
	A()
	{
		B b;
		std::cout<<"A Constructor:";
		b.Print();
		//	D d;
		//	d.Print();	//error: virtual void D::Print() const is private
	}

	void Print( const B &b)
	{
		std::cout<<"A->";
		b.Print();
	}

};

int _tmain(int argc, _TCHAR* argv[])
{
	A a;
	B b;
	D d;

	a.Print(b);
	a.Print(d);

	return 0;
}

posted on 2012-04-17 14:06  flydream  阅读(292)  评论(0编辑  收藏  举报