C++之友元:友元函數(shù)和友元類詳解
一、友元介紹
我們知道,類的成員函數(shù)可以訪問(wèn)同類的其他成員函數(shù),包括公有、私有和保護(hù)成員。而類的外部函數(shù)只能訪問(wèn)類的公有成員。
友元是一種允許非類成員函數(shù)訪問(wèn)類的非公有成員的一種機(jī)制。
可以把一個(gè)函數(shù)指定為類的友元,也可以把整個(gè)類指定為另一個(gè)類的友元。
友元函數(shù)
友元類
二、友元函數(shù)
友元函數(shù)在類作用域外定義,但它需要在類體中進(jìn)行說(shuō)明
為了與該類的成員函數(shù)加以區(qū)別,定義的方式是在類中用關(guān)鍵字friend說(shuō)明該函數(shù),格式如下:
friend 類型 友元函數(shù)名(參數(shù)表);
友元的作用在于提高程序的運(yùn)行效率
友元函數(shù)注意事項(xiàng):
1、友元函數(shù)不是類的成員函數(shù),在函數(shù)體中訪問(wèn)對(duì)象的成員,必須用對(duì)象名加運(yùn)算符“.”加對(duì)象成員名。但友元函數(shù)可以訪問(wèn)類中的所有成員(公有的、私有的、保護(hù)的),一般函數(shù)只能訪問(wèn)類中的公有成員。
2、友元函數(shù)不受類中的訪問(wèn)權(quán)限關(guān)鍵字限制,可以把它放在類的公有、私有、保護(hù)部分,但結(jié)果一樣。
3、某類的友元函數(shù)的作用域并非該類作用域。如果該友元函數(shù)是另一類的成員函數(shù),則其作用域?yàn)榱硪活惖淖饔糜?,否則與一般函數(shù)相同。
4、友元函數(shù)破壞了面向?qū)ο蟪绦蛟O(shè)計(jì)類的封裝性,所以友元函數(shù)如不是必須使用,則盡可能少用?;蛘哂闷渌侄伪WC封裝性。
#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類的友元函數(shù),可以訪問(wèn)類的私有數(shù)據(jù)成員。
三、友元類
如果某類B的成員函數(shù)會(huì)頻繁的存取另一個(gè)類A的數(shù)據(jù)成員, 而A的數(shù)據(jù)成員的Private/Protectd限制造成B存取的麻煩, B只能通過(guò)A的Public的成員函數(shù)進(jìn)行間接存取
把B做成A類的友元類,即A類向B類開(kāi)放其Private/Protectd內(nèi)容, 讓B直接存取
友元類:一個(gè)類可以作另一個(gè)類的友元
友元類的所有成員函數(shù)都是另一個(gè)類的友元函數(shù)
友元類的聲明:
friend class 類名;
友元類注意事項(xiàng):
1、友元關(guān)系是單向的
2、友元關(guān)系不能被傳遞
3、友元關(guān)系不能被繼承
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 類的成員函數(shù)就都可以訪問(wèn)Television類的所有成員,包括私有。
相關(guān)文章
C語(yǔ)言驅(qū)動(dòng)開(kāi)發(fā)之通過(guò)ReadFile與內(nèi)核層通信
驅(qū)動(dòng)與應(yīng)用程序的通信是非常有必要的,內(nèi)核中執(zhí)行代碼后需要將其動(dòng)態(tài)顯示給應(yīng)用層。為了實(shí)現(xiàn)內(nèi)核與應(yīng)用層數(shù)據(jù)交互則必須有通信的方法,微軟為我們提供了三種通信方式,本文先來(lái)介紹通過(guò)ReadFile系列函數(shù)實(shí)現(xiàn)的通信模式2022-09-09使用pthread庫(kù)實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端
使用pthread庫(kù)實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端,大家參考使用吧2014-01-01C語(yǔ)言實(shí)現(xiàn)貪吃蛇超詳細(xì)教程
本文詳細(xì)講解了C語(yǔ)言實(shí)現(xiàn)貪吃蛇的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12C++語(yǔ)言實(shí)現(xiàn)開(kāi)心消消樂(lè)
這篇文章主要為大家詳細(xì)介紹了C++語(yǔ)言實(shí)現(xiàn)開(kāi)心消消樂(lè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12VSCode配置C/C++環(huán)境的最新詳細(xì)教程
VisualStudioCode(簡(jiǎn)稱VSCode)是Microsoft開(kāi)發(fā)的代碼編輯器,它支持Windows,Linux和macOS等操作系統(tǒng)以及開(kāi)源代碼,下面這篇文章主要給大家介紹了關(guān)于VSCode配置C/C++環(huán)境的最新詳細(xì)教程,需要的朋友可以參考下2022-12-12C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06C語(yǔ)言二叉樹(shù)常見(jiàn)操作詳解【前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度】
這篇文章主要介紹了C語(yǔ)言二叉樹(shù)常見(jiàn)操作,結(jié)合實(shí)例形式詳細(xì)分析了基于C語(yǔ)言的二叉樹(shù)前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-04-04