日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【C++深度剖析教程6】C++之友元

發(fā)布時(shí)間:2023/12/10 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++深度剖析教程6】C++之友元 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這幾天在復(fù)習(xí)數(shù)學(xué)考試,都沒有學(xué)C++,今天抽空來學(xué)一點(diǎn)。

什么是友元?

  • 友元是C++中的一種關(guān)系
  • 友元發(fā)生在函數(shù)與類之間或者類與類之間
  • 友元關(guān)系是單向的,不能傳遞

在具體講解友元的性質(zhì)之前,我們先來看看一個(gè)程序,這個(gè)程序是計(jì)算兩點(diǎn)之間的距離:

#include <stdio.h> #include <math.h>class Point { private:double x;double y; public:Point(double x,double y){this->x = x; //this指針指向當(dāng)前的對(duì)象this->y = y;}double getX(){return x;}double getY(){return y;} };double func(Point& p1,Point& p2) {double ret = 0;ret = (p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) +(p1.getY() - p2.getY()) * (p1.getY() - p2.getY());ret = sqrt(ret);return ret; }int main() {Point p1(1,2);Point p2(10,20);printf("p1(%f,%f)\n",p1.getX(),p1.getY());printf("p2(%f,%f)\n",p2.getX(),p2.getY());printf("|p1-p2| = %f\n",func(p1,p2));return 0; }

上面代碼運(yùn)行結(jié)果為:

p1(1.000000,2.000000) p2(10.000000,20.000000) |p1-p2| = 20.124612

看著也沒什么大問題。下面我們來簡(jiǎn)單分析一下這個(gè)程序的實(shí)用性:進(jìn)行計(jì)算這個(gè)兩點(diǎn)之間的距離時(shí)的代碼為:

ret = (p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) +(p1.getY() - p2.getY()) * (p1.getY() - p2.getY());

進(jìn)行了8次函數(shù)的調(diào)用!!!這么簡(jiǎn)單的計(jì)算,就需要調(diào)用8次函數(shù),這效率之慢在當(dāng)初C++誕生的時(shí)候,是不被大多數(shù)人接受的,大多數(shù)人用C編程習(xí)慣了,都是可以直接這樣調(diào)用的:

ret = (p1.x - p2.x) * (p1.x - p2.x) +(p1.y - p2.y) * (p1.y - p2.y);

然而C++里面你就不能像上面那樣直接調(diào)用類(C里面可以是結(jié)構(gòu)體或者數(shù)組)的成員變量。因?yàn)樗莗rivate類型的變量。那么在C++誕生的那個(gè)年代,人們?yōu)榱俗孋++語(yǔ)言完全兼容C語(yǔ)言,就在C++中加入了友元的存在。那么友元的定義以及性質(zhì)是什么樣的呢?

  • 在類中以friend關(guān)鍵字聲明友元
  • 類的友元可以是其他類或者具體的函數(shù)
  • 友元不是類的一部分
  • 友元不受類中訪問級(jí)別的限制
  • 友元可以直接訪問具體類的所有成員

直接將上面的代碼修改一下看看:

#include <stdio.h> #include <math.h>class Point { private:double x;double y; public:Point(double x,double y){this->x = x; //this指針指向當(dāng)前的對(duì)象this->y = y;}double getX(){return x;}double getY(){return y;}friend double func(Point& p1,Point& p2)};double func(Point& p1,Point& p2) {double ret = 0;ret = (p1.x - p2.x) * (p1.x - p2.x) +(p1.y - p2.y) * (p1.y - p2.y);ret = sqrt(ret);return ret; }int main() {Point p1(1,2);Point p2(10,20);printf("p1(%f,%f)\n",p1.getX(),p1.getY());printf("p2(%f,%f)\n",p2.getX(),p2.getY());printf("|p1-p2| = %f\n",func(p1,p2));return 0; }

運(yùn)行結(jié)果為:

p1(1.000000,2.000000) p2(10.000000,20.000000) |p1-p2| = 20.124612

這樣看來,我們已經(jīng)實(shí)現(xiàn)了直接訪問類的私有成員變量。上面的代碼,func函數(shù)是Point類的友元,可以直接訪問Point的所有數(shù)據(jù)。但是這樣做,又不好,為什么呢?
友元的尷尬:

  • 友元是為了兼顧C語(yǔ)言的高效性而誕生的
  • 友元直接破壞了面向?qū)ο蟮姆庋b性
  • 友元在實(shí)際產(chǎn)品中的高效是得不償失的
  • 友元在現(xiàn)代軟件工程中已經(jīng)被逐漸遺棄

雖然基于以上的尷尬讓友元這個(gè)功能在現(xiàn)代軟件工程中很少被使用,但是我們學(xué)習(xí)嘛,肯定是都要學(xué)的,哈哈~

友元需要注意的一些事項(xiàng):

  • 友元關(guān)系不具備傳遞性
  • 類的友元可以是其他類的成員函數(shù)
  • 類的友元可以是某個(gè)完整的類(所有的成員函數(shù)都是友元)

    下面我們?cè)俜治鲆粋€(gè)代碼,來看看友元的真實(shí)面目:
#include <stdio.h>class ClassC {const char* n; public:ClassC(const char* n){this->n = n;}friend class ClassB; };class ClassB {const char* n; public:ClassB(const char* n){this->n = n;}void getClassCName(ClassC& c){printf("c.n = %s\n", c.n);}friend class ClassA; };class ClassA {const char* n; public:ClassA(const char* n){this->n = n;}void getClassBName(ClassB& b){printf("b.n = %s\n", b.n);}/*void getClassCName(ClassC& c){printf("c.n = %s\n", c.n);}*/ };int main() {ClassA A("A");ClassB B("B");ClassC C("C");A.getClassBName(B);B.getClassCName(C);return 0; }

運(yùn)行結(jié)果為:

b.n = B c.n = C

分析代碼知:類B是C的友元,類A是B的友元,所以在B中可以直接訪問C的私有成員變量,在A中可以直接訪問B的成員變量。 那么在A中能否直接訪問C呢?試驗(yàn)一下將上面的代碼注釋掉得部分恢復(fù),編譯運(yùn)行,運(yùn)行結(jié)果為:

test.cpp: In member function ‘void ClassA::getClassCName(ClassC&)’: test.cpp:6: error: ‘const char* ClassC::n’ is private test.cpp:44: error: within this context

很顯然,A是不能訪問C的私有成員的。

總結(jié)一下:

  • 友元是為了兼顧C(jī)語(yǔ)言的高效而誕生的
  • 友元直接破壞了面向?qū)ο蟮姆庋b性
  • 友元關(guān)系不具備傳遞性
  • 類的友元可以是其他類的成員函數(shù)
  • 類的友元可以是某個(gè)完整的類

想獲得各種學(xué)習(xí)資源以及交流學(xué)習(xí)的加我(有我博客中寫的代碼的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流關(guān)于嵌入式,操作系統(tǒng),C++語(yǔ)言,C語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)等技術(shù)問題。

總結(jié)

以上是生活随笔為你收集整理的【C++深度剖析教程6】C++之友元的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。