面向對象編程的一個重要思想就是實現數據隱藏(類的封裝特性),即:非成員函數不能訪問private 或者 protected 變量。
有些時候我們需要不經成員函數而訪問private 或者 protected數據,那就需要用到 友元函數 或者友元類。
1. 友元函數
使用 friend 關鍵字在類內任意位置聲明函數爲友元函數。 而且,當要訪問
非static成員時,需要對象作爲參數。
如下:
#include <iostream>
using namespace std;
class Distance
{
private:
int meter;
public:
Distance(): meter(0) { }
private:
// 可以在任意位置聲明友元函數,對象作爲參數
friend int addFive(Distance);
};
int addFive(Distance d)
{
d.meter += 5;
return d.meter;
}
int main()
{
Distance D;
cout<<"Distance: "<< addFive(D);
return 0;
}
\\ output
Distance: 5
上面的例子只是舉例友元函數的用法,其實沒什麼意義。 友元函數在操作兩個不同類的對象時才體現出它的價值。
如下面的例子:
#include <iostream>
using namespace std;
// 提前聲明類B
class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// 聲明友元函數
friend int add(A, B);
};
class B {
private:
int numB;
public:
B(): numB(1) { }
// 聲明友元函數
friend int add(A , B);
};
// 兩個不同類的私有變量相加
int add(A objectA, B objectB)
{
return (objectA.numA + objectB.numB);
}
int main()
{
A objectA;
B objectB;
cout<<"Sum: "<< add(objectA, objectB);
return 0;
}
2 友元類
當一個類成爲友元類時,其所有成員函數自動成爲友元函數,如下例。 B中的所有函數都是A的友元函數,因此B中函數可以訪問A的private 或者 protected數據。
... .. ...
class B;
class A
{
// class B is a friend class of class A
friend class B;
... .. ...
}
class B
{
... .. ...
}
3 友元的注意事項
- (1)應慎用友元。 因爲其會破壞面向對象的封裝特性,造成一定的安全問題。
- (2)友元不是相互的。 類A是B的友元,但B不會自動變成A的友元
- (3)友元是不可繼承的。
- (4)普通成員函數有this指針,static和友元函數沒有。
參考資料
- C++ friend Function and friend Classes https://www.programiz.com/cpp-programming/friend-function-class