1. 程式人生 > >待補遺(6)[C++]兩個類如何通過友元宣告互相訪問對方的非公有成員

待補遺(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;
}
執行結果:


二、若類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;
}
執行結果:

注意的問題:

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;
}
執行結果:


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的友元函式
};
以上程式碼,可以執行成功!