亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++中友元的實例詳解

2020-01-26 13:55:59
字體:
來源:轉載
供稿:網友

C++中友元的實例詳解

盡管友元被授予從外部訪問類的私有部分的權限,但他們并不與面向對象的編程思想相悖;相反他提高了公共接口的靈活性。

一、友元類

友元聲明可以位于公有、私有活保護部分、其所在位置無關緊要

我直接貼出一個摘自< c++ primer plus >的例子來演示 c++ 友元類

其中 Remote 為 Tv的友元類。

Tv.h

#ifndef TV_H_#define TV_H_/*一個類 電視 */class Tv{public:  friend class Remote; //Remote類可以訪問Tv Privite 的私有部分  enum {    off,on  //開關   };  enum   {    MinVal,MaxVal=20  //音量  };  enum {    Antena,Cable //使用的天線、還是電纜  };  enum   {    TV ,DVD  //工作模式  };  Tv(int s = off, int mc = 125) :state(s), volume(5), maxchannel(mc),    channel(5), mode(Cable), input(TV) {}  void onoff() { state = (state == on) ? off : on; }  bool ison()const { return state == on; }  bool volup();  //增大聲音  bool voldown(); //減小聲音  void chanup(); //頻道 +  void chandown();//頻道 -  void set_mode() { mode = (mode == Antena) ? Cable : Antena; }  void set_input() { input = (input == TV) ? DVD : TV; }  void settings()const; //顯示所有設置private:  int state;  // 開或者 關  int volume; // 音量  int maxchannel; //最大  int channel;  //當前頻道  int mode;  // 廣播還是 電纜  int input; //Tv 或者 DVD};/*Remote 的定義 (遙控器) */class Remote {private :  int mode; // 控制 TV 或 DVDpublic:  Remote(int m = Tv::TV) :mode(m) {}  bool volup(Tv & t) { return t.volup(); }  bool voldown(Tv & t) { return t.voldown(); }  void onoff(Tv & t) { return t.onoff(); }  void chanup(Tv & t) { return t.chanup(); }  void chandown(Tv & t) { return t.chandown(); }  void set_chan(Tv &t, int c) { t.channel = c; } //訪問了Tv的私有成員  void set_mode(Tv &t) { t.set_mode(); }  void set_input(Tv &t) { t.set_input(); }};#endif // TV_H_

Tv.cpp

#include "stdafx.h"#include "Tv.h"#include <iostream>bool Tv::volup() {  if (volume < MaxVal) {    volume++;    return true;  }  else {    return false;  }}bool Tv::voldown() {  if (volume > MinVal) {    volume--;    return true;  }  else {    return false;  }}void Tv::chanup() {  if (channel < maxchannel) channel++;  else channel = 1;}void Tv::chandown() {  if (channel > 1) channel--;  else channel = maxchannel;}void Tv::settings() const {  using std::cout;  using std::endl;  cout << "TV is " << (state == off ? "off" : "on") << endl;  if (state == on) {    cout << "Volume setting =" << volume << endl;    cout << "Channel setting = " << channel << endl;    cout << "Mode = " << (mode == Antena ? "antenna" : "cable") << endl;    cout << "Input = " << (input == TV ? "TV" : "DVD") << endl;  }}

測試代碼:

#include "stdafx.h"#include "tv.h"#include <iostream>int main(){  using std::cout;  Tv s42;  cout << "Initial settings for 42 /" Tv: /n";  s42.settings();  s42.onoff();  s42.chanup();  cout << " /n Adjusted settings for 42 /" Tv: /n";  s42.chanup();  cout << "/n Adjusted settings for 42 /" Tv: /n";  s42.settings();  Remote grey;  grey.set_chan(s42, 10);  grey.volup(s42);  grey.volup(s42);  cout << " /n s42 /" settings after using remote: /n";  s42.settings();  Tv s58(Tv::on);  s58.set_mode();  grey.set_chan(s58, 58);  cout << " /n s58 /" setting: /n";  s58.settings();  system("pause");  return 0;}

運行結果:

Initial settings for 42 " Tv:TV is off Adjusted settings for 42 " Tv: Adjusted settings for 42 " Tv:TV is onVolume setting =5Channel setting = 7Mode = cableInput = TV s42 " settings after using remote:TV is onVolume setting =7Channel setting = 10Mode = cableInput = TV s58 " setting:TV is onVolume setting =5Channel setting = 58Mode = antennaInput = TV請按任意鍵繼續. . .

上述代碼中將Remote類設置成為了Tv類的友元類,但事實上我們看到:唯一訪問Tv的成員的方法是void set_chan(Tv &t, int c) { t.channel = c; } ,因此它是唯一需要友元的方法。因此不必讓整個類成為友元,這就引出了我們下面要講的的友元成員函數。

二、友元成員函數

我們要再Tv中將Remote::set_chan()設置成友元:

clas Tv{  friend void Remote::set_chan(Tv & t,int c ) ;}

然而要使編譯器能夠處理這條語句,它必須知道Remote的定義。否則,它無法知道Remote是一個類。而 set_chan是這個類的方法。這意味著應將Remote的定義放到Tv的定義前面。Remote的方法提到了Tv對象,而意味著Tv定義應當位于Remote定義之前,避開這種循環依賴的方法是,使用前向聲明。
所以應該這樣:

class Tv ; //前向聲明class Remote{...}class Tv {...}

這里還有一個麻煩就是:

Remote 包含了內聯代碼例如:void onoff(Tv &t) {t.onoff();};

由于這將調用Tv的一個方法,所以編譯器此時已經看到了Tv類的聲明,這樣才能知道Tv有哪些方法,但正如看到的,該聲明位于Remote聲明的后面。這種問題的解決方法是:使用Remote聲明中只包含方法聲明,并將實際的定義放到Tv類之后。 所以最終應該這樣:

class Tv; //前向聲明class Remote {...} //如要用到Tv 只能是方法聲明class Tv{...}//接著寫Remote的定義

這里通過方法定義中使用 inline關鍵字,仍然可以使方法稱為內聯方法
所以程序最終將tv.h改為:

#ifndef TV_H_#define TV_H_class Tv; //前向聲明class Remote {public:  enum {    off, on  //開關   };  enum  {    MinVal, MaxVal = 20  //音量  };  enum {    Antena, Cable //使用的天線、還是電纜  };  enum  {    TV, DVD  //工作模式  };private:  int mode; // 控制 TV 或 DVDpublic:  Remote(int m = TV) :mode(m) {}  //用到了Tv 只能是聲明  bool volup(Tv & t);  bool voldown(Tv & t);  void onoff(Tv & t);  void chanup(Tv & t);  void chandown(Tv & t);  void set_chan(Tv &t, int c);  void set_mode(Tv &t);  void set_input(Tv &t);};class Tv{public:  friend void Remote::set_chan(Tv & t,int c); //友元成員函數  enum {    off, on  //開關   };  enum  {    MinVal, MaxVal = 20  //音量  };  enum {    Antena, Cable //使用的天線、還是電纜  };  enum  {    TV, DVD  //工作模式  };  Tv(int s = off, int mc = 125) :state(s), volume(5), maxchannel(mc),    channel(5), mode(Cable), input(TV) {}  void onoff() { state = (state == on) ? off : on; }  bool ison()const { return state == on; }  bool volup();  //增大聲音  bool voldown(); //減小聲音  void chanup(); //頻道 +  void chandown();//頻道 -  void set_mode() { mode = (mode == Antena) ? Cable : Antena; }  void set_input() { input = (input == TV) ? DVD : TV; }  void settings()const; //顯示所有設置private:  int state;  // 開或者 關  int volume; // 音量  int maxchannel; //最大  int channel;  //當前頻道  int mode;  // 廣播還是 電纜  int input; //Tv 或者 DVD};inline bool Remote::volup(Tv & t) { return t.volup(); }inline bool Remote::voldown(Tv & t) { return t.voldown(); }inline void Remote::onoff(Tv & t) { return t.onoff(); }inline void Remote::chanup(Tv & t) { return t.chanup(); }inline void Remote::chandown(Tv & t) { return t.chandown(); }inline void Remote::set_chan(Tv &t, int c) { t.channel = c; }inline void Remote::set_mode(Tv &t) { return t.set_mode(); }inline void Remote::set_input(Tv &t) { return t.set_input(); }#endif // TV_H_

測試結果不變。

*另外:也可一個將內聯函數放在tv.cpp中,但必須去掉inline關鍵字,這樣函數的連接性將成為外部的。

三、其他友元關系

1、上面的代碼表示的是Remote是Tv的友元。但我們有時也會用到2個類互相友元。即Remote是Tv的友元,同時 Tv又是Remote的友元

他們定義與下面類似:

class Remoteclass Tv{friend clas Remotepublic:  void buzz(Remote & r) ;  ...}class Remote{friend class Tv;public:  void Bool volup(Tv & t){t.volup();}  ...}inline void Tv::buzz(Remote & r){...}

由于Remote的聲明位于Tv聲明的后面,所以可以在類的定義Remote::volup(),但Tv::buzz()方法必須在Tv聲明的外部定義,使其位于Remote聲明的外面。如果不希望buzz()是內聯的,則應在一個單獨的方法定義文件中定義它。

2、共同的友元。

需要使用友元的另一種情況是,函數需要訪問兩個類的私有數據。它可以是一個類的友元,同時是另一個類的友元。示例如下:

class Analyzer;class Probe{  friend void sync (Analyzer & a,const Probe & p) ;  friend void sync (Probe & p,const Analyzer & a);  ...};class Analyzer{  friend void sync (Analyzer & a,const Probe & p) ;  friend void sync (Probe & p,const Analyzer & a);}inline void sync (Analyzer & a,const Probe & p){  ...}inline void sync (Probe & p,const Analyzer & a){  ...}

如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产91久久久久久| 欧美黑人一区二区三区| 国产日产欧美精品| 91精品啪在线观看麻豆免费| 日韩电影免费在线观看中文字幕| 久久久精品国产亚洲| 91高潮精品免费porn| 欧美激情一区二区三区成人| 91青草视频久久| 在线视频亚洲欧美| 国产视频在线一区二区| 日本最新高清不卡中文字幕| 精品视频在线导航| 久久久精品在线观看| 日韩av不卡在线| 国产精品一区二区久久| 一区二区欧美激情| 在线看日韩欧美| 亚洲欧美综合v| 国产福利成人在线| 国产精品久久久久国产a级| 欧美国产日韩一区二区在线观看| 亚洲第一页中文字幕| 亚洲精品影视在线观看| 欧美另类69精品久久久久9999| 日韩成人av在线播放| 最新91在线视频| 中文字幕亚洲字幕| 国产精品第七影院| 亚洲欧美国产精品专区久久| 亚洲福利视频二区| 精品人伦一区二区三区蜜桃网站| 少妇久久久久久| 亚洲欧美日韩一区二区在线| 亚洲男人的天堂在线| www.亚洲一区| 永久免费毛片在线播放不卡| 国产精品99久久久久久www| 国产视频久久网| 亚洲成人久久久久| 91手机视频在线观看| 国模极品一区二区三区| 久久全球大尺度高清视频| 久久久久久免费精品| 日韩av在线免播放器| 美女撒尿一区二区三区| 亚洲电影免费观看高清完整版在线| 国产ts一区二区| 国产成人精品视频在线观看| 国产日韩欧美夫妻视频在线观看| 国产999视频| 国产精品九九九| 日韩精品中文字幕在线播放| 精品无人国产偷自产在线| 91欧美精品成人综合在线观看| 97色在线视频观看| 欧美综合激情网| 色综合久久天天综线观看| 亚洲自拍欧美另类| 亚洲xxxx妇黄裸体| 久久久91精品国产| 国产成人综合久久| 日韩精品高清在线| 91影视免费在线观看| 国产不卡一区二区在线播放| 亚洲一区二区三区四区在线播放| 亚洲片在线观看| 免费91麻豆精品国产自产在线观看| 蜜臀久久99精品久久久久久宅男| 正在播放亚洲1区| 久久综合伊人77777蜜臀| 精品久久久91| 91最新国产视频| 亚洲美女自拍视频| 青草热久免费精品视频| 最新国产成人av网站网址麻豆| 国产精品丝袜视频| 成人激情电影一区二区| 国产精品老牛影院在线观看| 中文字幕免费精品一区高清| 日韩精品在线视频观看| 九九热精品视频在线播放| 亚洲天堂男人天堂女人天堂| 中文字幕v亚洲ⅴv天堂| 亚洲精品一区中文| 亚洲欧美一区二区三区在线| 91免费的视频在线播放| 成人国产精品免费视频| 日韩国产一区三区| 中文字幕自拍vr一区二区三区| 亚洲一区二区三区在线视频| 国产精品视频成人| 国产91对白在线播放| 久久精品国产综合| 国产精品成熟老女人| 欧美日韩国产精品一区二区三区四区| 国产精品视频不卡| 亚洲香蕉av在线一区二区三区| 久久久久国产精品免费| 亚洲三级免费看| 日韩精品在线影院| 国产日韩在线精品av| 77777少妇光屁股久久一区| 亚洲第一男人av| 色偷偷偷亚洲综合网另类| 久久夜精品香蕉| 色播久久人人爽人人爽人人片视av| 日本精品视频网站| 精品日本高清在线播放| 色综合导航网站| 国产91精品视频在线观看| 国内精品一区二区三区四区| 日韩精品在线免费| 国产精品美女免费| 久久久视频精品| 欧美老少配视频| 91成人在线播放| 亚洲人成在线电影| 国产欧美一区二区三区在线| 中文字幕日韩av电影| 91精品视频在线看| 成人免费视频在线观看超级碰| 欧美成人免费一级人片100| 久久亚洲精品国产亚洲老地址| 久久亚洲电影天堂| 亚洲国模精品一区| 亚洲xxxx妇黄裸体| 国产色综合天天综合网| 国产mv久久久| 国产裸体写真av一区二区| 欧美激情性做爰免费视频| 77777亚洲午夜久久多人| 日韩视频在线免费观看| 欧美日韩国产精品一区二区不卡中文| 九九热r在线视频精品| 亚洲国产精品va在线看黑人| 日韩精品极品在线观看播放免费视频| 成人妇女免费播放久久久| 动漫精品一区二区| 日韩小视频在线观看| 国产国产精品人在线视| 日韩成人av网址| 国产精品91久久久久久| 91亚洲精品一区二区| 国产精品ⅴa在线观看h| 久久精品国产亚洲| 欧美极品少妇全裸体| 久精品免费视频| 日韩欧美精品网站| 欧美激情国产精品| 久久精品在线视频| 日本成人免费在线| 国产美女久久精品香蕉69| 欧美福利视频在线| 亚洲第一区第一页| 国产精品美女av| 黄网站色欧美视频| 在线播放日韩专区| 午夜精品美女自拍福到在线| 668精品在线视频| 国产成人97精品免费看片| 92裸体在线视频网站| 欧美成年人视频网站| 91香蕉电影院|