天天看点

待补遗(6)[C++]两个类如何通过友元声明互相访问对方的非公有成员

1.设有类A,和类B两个类,假定类A的声明在类B之前(类的声明总会有先后之分)

2.类A与类B,各自具有一个private权限的func函数。

一、类A,类B的声明如下(定义在在同一个源文件中):

#include <iostream>

class A{
private:
	void func()
	{
		std::cout << "A::func()" << std::endl;
	}
};

class B{
private:
	void func()
	{
		std::cout << "B::func()" << std::endl;
	}
};

int main()
{

	system("pause");
	return 0;
}
           

执行结果:

待补遗(6)[C++]两个类如何通过友元声明互相访问对方的非公有成员

二、若类A,有一个成员函数call_func_of_B(B &b)想要调用类B的private成员函数func(),为了

解决这个问题可将call_func_of_B(B &b)函数声明为类B的友元函数,代码书写如下:

#include <iostream>

class B;//由于类B的定义在类A之后,所以用到类B的声明时,使用前向声明

class A{
private:
	void func()
	{
		std::cout << "A::func()" << std::endl;
	}
public:
	void call_func_of_B(B &b);//可以使用类B定义指针,引用,对象,因为上文有前向声明
};

class B{
private:
	void func()
	{
		std::cout << "B::func()" << std::endl;
	}
	friend void A::call_func_of_B(B &b);//友元声明将类A的成员函数声明为类B的友元函数
};
//定义类A成员函数
void A::call_func_of_B(B &b)
{
	b.func();
}
           

测试代码:

int main(){
	A a;
	B b;
	a.call_func_of_B(b);

	system("pause");
	return 0;
}
           

执行结果:

待补遗(6)[C++]两个类如何通过友元声明互相访问对方的非公有成员

注意的问题:

1.不能将call_func_of_B()函数的定义放在它声明的地方,代码如下:

#include <iostream>

class B;//由于类B的定义在类A之后,所以用到类B的声明时,使用前向声明

class A{
private:
	void func()
	{
		std::cout << "A::func()" << std::endl;
	}
public:
	void call_func_of_B(B &b)//可以使用类B定义指针,引用,对象,因为上文有前向声明
	{
		//b.func();
		//前向声明能力有限,对于类B的细节,只有定义之后才能访问
	}
};
           

2.也不能在声明友元函数是对call_func_of_B()函数进行定义

class B{
private:
	void func()
	{
		std::cout << "B::func()" << std::endl;
	}
	friend void A::call_func_of_B(B &b)//友元声明将类A的成员函数声明为类B的友元函数
	{
		//b.func();//C3060 不允许对使用限定名的友元函数进行定义
	}

};
           

对于C3060编译器错误,参见MSDN: http://msdn.microsoft.com/en-us/library/9h84hcy4(v=vs.90).aspx

三、由于类B的定义晚于类A的定义,若要使类B的成员访问类A的非public成员,需将类B设为类A的友元类

#include <iostream>

class B;//由于类B的定义在类A之后,所以用到类B的声明时,使用前向声明

class A{
private:
	void func()
	{
		std::cout << "A::func()" << std::endl;
	}
public:
	void call_func_of_B(B &b);//可以使用类B定义指针,引用,对象,因为上文有前向声明
	friend class B;//此时若要用B的成员函数访问A的非public成员,只能将类B设为类A的友元类
};

class B{
private:
	void func()
	{
		std::cout << "B::func()" << std::endl;
	}
public:
	void call_func_of_A(A &a);
	friend void A::call_func_of_B(B &b);//友元声明将类A的成员函数声明为类B的友元函数
};
void A::call_func_of_B(B &b)
{
	b.func();
}
void B::call_func_of_A(A &a)
{
	a.func();
}


int main()
{
	A a;
	B b;
	a.call_func_of_B(b);
	b.call_func_of_A(a);

	system("pause");
	return 0;
}
           

执行结果:

待补遗(6)[C++]两个类如何通过友元声明互相访问对方的非公有成员

1.同样,类B的成员函数可在类B中定义,也可在类B作用域外定义

class B{
private:
	void func()
	{
		std::cout << "B::func()" << std::endl;
	}
public:
	void call_func_of_A(A &a)
	{
		a.func();
	}

	friend void A::call_func_of_B(B &b);//友元声明将类A的成员函数声明为类B的友元函数
};
           

以上代码,可以执行成功!

继续阅读