一、友元介紹
我們知道,類的成員函數可以訪問同類的其他成員函數,包括公有、私人和保護成員。而類的外部函數只能訪問類的公有成員。
友元是一種允許非類成員函數訪問類的非公有成員的一種機制。
可以把一個函數指定為類的友元,也可以把整個類指定為另一個類的友元。
友元函數
友元類
二、友元函數
友元函數在類範圍外定義,但它需要在類體中進行說明
為了與該類的成員函數加以區別,定義的方式是在類中用關鍵字friend說明該函數,格式如下:
friend 類型 友元函數名(參數表);
友元的作用在於提高程式的運行效率
友元函數注意事項:
1、友元函數不是類的成員函數,在函數體中訪問對象的成員,必須用對象名加運算子“.”加對象成員名。但友元函數可以訪問類中的所有成員(公有的、私人的、保護的),一般函數只能訪問類中的公有成員。
2、友元函數不受類中的存取權限關鍵字限制,可以把它放在類的公有、私人、保護部分,但結果一樣。
3、某類的友元函數的範圍並非該類範圍。如果該友元函數是另一類的成員函數,則其範圍為另一類的範圍,否則與一般函數相同。
4、友元函數破壞了物件導向程式設計類的封裝性,所以友元函數如不是必須使用,則儘可能少用。或者用其他手段保證封裝性。
複製代碼 代碼如下:
#include <math.h>
#include <iostream>
using namespace std;
class Point
{
friend double Distance(const Point &p1, const Point &p2);
public:
Point(int x, int y);
private:
int x_;
int y_;
};
Point::Point(int x, int y) : x_(x), y_(y)
{
}
double Distance(const Point &p1, const Point &p2)
{
double dx = p1.x_ - p2.x_;
double dy = p1.y_ - p2.y_;
return sqrt(dx * dx + dy * dy);
}
int main(void)
{
Point p1(3, 4);
Point p2(6, 9);
cout << Distance(p1, p2) << endl;
return 0;
}
程式中Distance 是Point類的友元函數,可以訪問類的私人資料成員。
三、友元類
如果某類B的成員函數會頻繁的存取另一個類A的資料成員, 而A的資料成員的Private/Protectd限制造成B存取的麻煩, B只能通過A的Public的成員函數進行間接存取
把B做成A類的友元類,即A類向B類開放其Private/Protectd內容, 讓B直接存取
友元類:一個類可以作另一個類的友元
友元類的所有成員函數都是另一個類的友元函數
友元類的聲明:
friend class 類名;
友元類注意事項:
1、友元關係是單向的
2、友元關係不能被傳遞
3、友元關係不能被繼承
TeleController.h :
複製代碼 代碼如下:
#ifndef _TELE_CONTROLLER_H_
#define _TELE_CONTROLLER_H_
class Television;
class TeleController
{
public:
void VolumeUp(Television &tv);
void VolumeDown(Television &tv);
void ChanelUp(Television &tv);
void ChanelDown(Television &tv);
};
#endif // _TELE_CONTROLLER_H_
TeleController.cpp :
複製代碼 代碼如下:
#include "TeleController.h"
#include "Television.h"
void TeleController::VolumeUp(Television &tv)
{
tv.volume_ += 1;
}
void TeleController::VolumeDown(Television &tv)
{
tv.volume_ -= 1;
}
void TeleController::ChanelUp(Television &tv)
{
tv.chanel_ += 1;
}
void TeleController::ChanelDown(Television &tv)
{
tv.volume_ -= 1;
}
Television.h:
複製代碼 代碼如下:
#ifndef _TELEVISION_H_
#define _TELEVISION_H_
class TeleController;
class Television
{
friend class TeleController;
public:
Television(int volume, int chanel);
private:
int volume_;
int chanel_;
};
#endif // _TELEVISION_H_
Television.cpp:
複製代碼 代碼如下:
#include "Television.h"
Television::Television(int volume, int chanel) : volume_(volume), chanel_(chanel)
{
}
main.cpp:
複製代碼 代碼如下:
#include "Television.h"
#include "TeleController.h"
#include <iostream>
using namespace std;
int main(void)
{
Television tv(1, 1);
TeleController tc;
tc.VolumeUp(tv);
return 0;
}
將TeleController 類作為Television類的友元類,這樣TeleController 類的成員函數就都可以訪問Television類的所有成員,包括私人。