網站首頁 編程語言 正文
一.友元函數
友元函數可以是普通函數或者類成員函數。
先看普通函數聲明為友元函數:
如下所示:
#include#include using namespace std; class Point { //普通函數聲明為類的友元函數 friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2); public: Point(double x=0, double y=0) :_x(x), _y(y) {} double getPointXAxis() const { return this->_x; } double getPointYAxis() const { return this->_y; } private: double _x; double _y; }; //計算兩點的距離 double TwoPointsDistant(const Point& pnt1, const Point& pnt2) { return sqrt( pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2) ); } int main() { Point point1(1.1,2.2); Point point2(3.3, 4.4); cout << TwoPointsDistant(point1, point2) << endl; system("pause"); return 0; }
這里說明一點:TwoPointsDistant()函數必須在Point類的定義下面
,至于原因,很簡單,你若放在Point上面,Point的數據成員_x和_y都沒定義呢,你用個錘子。
再看類成員函數聲明為友元函數:
還以上面的類為例,現在加一個_PointMove_類,它有一個成員函數_PointAxisAddOne,_作用是將點的坐標都加1。如下:
class PointMove { public: void PointAxisAddOne(Point& pnt); };
這里就出現了一個問題:_Point_和_PointMove_哪個放在前面?先給出答案,應該把_PointMove_放在前面,并且是必須的,如下:
class Point;//前向聲明Point class PointMove { public: void PointAxisAddOne(Point& pnt); }; class Point { //普通函數聲明為類的友元函數 friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2); //類成員函數聲明為友元 friend void PointMove::PointAxisAddOne(Point& pnt); /*這里同前*/ }; //類成員函數的定義 void PointMove::PointAxisAddOne(Point& pnt) { pnt._x = pnt._x + 1; pnt._y = pnt._y + 1; }
這里注意,對于類的成員函數,聲明為其他類的友元函數時需要加上類的作用域,即指出該函數屬于哪個類。如上面的_PointMove::_。?
同時,需要說明的是,PointAxisAddOne()函數的定義是必須放在Point類定義后面的,這和普通函數的道理是一樣的。
最后說明
1.一個函數Func被聲明為類A的友元函數,那么是不能直接使用this指針來訪問類A的數據成員的(當然,若Func是類B的成員函數,它可以通過this訪問類B的數據成員),這和成員函數不同。
2.一個函數Func為什么要聲明為某個類A的友元,就是因為函數的參數類型為類A類型,我想訪問這個類對象的數據成員
,所以被聲明為類A的友元函數的參數類型必定為類A,如friend Func(A& obj);
二.友元類
若是將一個類C都聲明為另一個類A的友元類,則類C中的成員函數均可訪問類A中的私有數據成員。如下:
class Point { //友元類 friend class PointInfo; ... } class PointInfo { public: //打印點所處象限 void PrintQuadrant(const Point& pnt) const { if (pnt._x > 0 && pnt._y > 0) cout << "點"<<"(" << pnt._x << "," << pnt._y<<")" <<"處于第一象限" << endl; } };
當然,你也可以把_PointInfo_寫在_Point_前,只是函數_PrintQuadrant()_的定義就不能在類內實現了,只能在_Point_后實現,原因和前面一樣,不再贅述。
三.完整示例:
#include#include using namespace std; class Point; class PointMove { public: void PointAxisAddOne(Point& pnt); }; class PointInfo { public: //打印點所處象限 void PrintQuadrant(const Point& pnt) const; }; class Point { friend class PointInfo; friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2); friend void PointMove::PointAxisAddOne(Point& pnt); public: Point(double x=0, double y=0) :_x(x), _y(y) {} double getPointXAxis() const { return this->_x; } double getPointYAxis() const { return this->_y; } void PrintAxis(const Point& pnt) const { } private: double _x; double _y; }; //打印點所處象限 void PointInfo::PrintQuadrant(const Point& pnt) const { if (pnt._x > 0 && pnt._y > 0) cout << "點"<<"(" << pnt._x << "," << pnt._y<<")" <<"處于第一象限" << endl; } void PointMove::PointAxisAddOne(Point& pnt) { pnt._x = pnt._x + 1; pnt._y = pnt._y + 1; } double TwoPointsDistant(const Point& pnt1, const Point& pnt2) { return sqrt( pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2) ); } int main() { Point point1(1.1,2.2); Point point2(3.3, 4.4); cout << TwoPointsDistant(point1, point2) << endl; PointInfo pf; pf.PrintQuadrant(point1); system("pause"); return 0; }
VS2015打印結果:
四.同一個類(class)的類對象(object)互為友元
還以上面給出的例子為基礎,現在在_Point_類加一個成員函數func(const Point& pnt),它返回點的x軸和y軸的和。如下所示。
class Point { /*這里同上*/ double func(const Point& pnt) { return pnt._x + pnt._y; } private: double _x; double _y; };
現在我生成兩個對象,并作如下操作:
Point point1(1.1,2.2); Point point2(3.3, 4.4); cout << point1.func(point2) << endl;
最后的結果是打印出7.7。看到這里不知道你有沒有疑問:為什么可以通過point1直接訪問point2的私有數據成員,而沒有將func()聲明為友元函數?侯捷老師是這么解釋的:相同class的各個objects之間互為友元。
所以對于一個類A,若有一個成員函數Fun(A& arg),可以通過arg直接訪問A的私有數據成員。
總結
原文鏈接:https://blog.csdn.net/weixin_43744293/article/details/123327548
相關推薦
- 2022-08-15 Android開發gradle拉取依賴的加速配置_Android
- 2022-09-23 Pandas中Apply函數加速百倍的技巧分享_python
- 2021-12-04 C#獲取Windows10屏幕縮放比例的操作方法_C#教程
- 2022-03-31 nginx平滑重啟和平滑升級的圖文教程_nginx
- 2022-06-10 使用Android實現一個懸浮在軟鍵盤上的輸入欄_Android
- 2022-09-19 React?Hook?四種組件優化總結_React
- 2022-05-06 Python判斷字符串中是否有整數、小數、百分數
- 2022-07-03 python爬蟲lxml庫解析xpath網頁過程示例_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支