最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中友元的實例詳解

 更新時間:2017年09月09日 09:48:49   投稿:lqh  
這篇文章主要介紹了C++中友元的實例詳解的相關(guān)資料,希望通過本文大家能掌握友元的使用方法,需要的朋友可以參考下

C++中友元的實例詳解

盡管友元被授予從外部訪問類的私有部分的權(quán)限,但他們并不與面向?qū)ο蟮木幊趟枷胂嚆?;相反他提高了公共接口的靈活性。

一、友元類

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

我直接貼出一個摘自< 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  //開關(guān) 
  };
  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; //顯示所有設(shè)置


private:
  int state;  // 開或者 關(guān)
  int volume; // 音量
  int maxchannel; //最大
  int channel;  //當前頻道
  int mode;  // 廣播還是 電纜
  int input; //Tv 或者 DVD
};

/*Remote 的定義 (遙控器) */
class Remote {
private :
  int mode; // 控制 TV 或 DVD
public:
  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;
}

運行結(jié)果:

Initial settings for 42 " Tv:
TV is off

 Adjusted settings for 42 " Tv:

 Adjusted settings for 42 " Tv:
TV is on
Volume setting =5
Channel setting = 7
Mode = cable
Input = TV

 s42 " settings after using remote:
TV is on
Volume setting =7
Channel setting = 10
Mode = cable
Input = TV

 s58 " setting:
TV is on
Volume setting =5
Channel setting = 58
Mode = antenna
Input = TV
請按任意鍵繼續(xù). . .

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

二、友元成員函數(shù)

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

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

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

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

這里還有一個麻煩就是:

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

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

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

這里通過方法定義中使用 inline關(guān)鍵字,仍然可以使方法稱為內(nèi)聯(lián)方法
所以程序最終將tv.h改為:

#ifndef TV_H_
#define TV_H_
class Tv; //前向聲明
class Remote {

public:
  enum {
    off, on  //開關(guān) 
  };
  enum
  {
    MinVal, MaxVal = 20  //音量
  };
  enum {
    Antena, Cable //使用的天線、還是電纜
  };
  enum
  {
    TV, DVD  //工作模式
  };

private:
  int mode; // 控制 TV 或 DVD
public:
  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); //友元成員函數(shù)
  enum {
    off, on  //開關(guān) 
  };
  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; //顯示所有設(shè)置
private:
  int state;  // 開或者 關(guān)
  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_

測試結(jié)果不變。

*另外:也可一個將內(nèi)聯(lián)函數(shù)放在tv.cpp中,但必須去掉inline關(guān)鍵字,這樣函數(shù)的連接性將成為外部的。

三、其他友元關(guān)系

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

他們定義與下面類似:

class Remote
class Tv
{
friend clas Remote
public:
  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()是內(nèi)聯(lián)的,則應(yīng)在一個單獨的方法定義文件中定義它。

2、共同的友元。

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

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)
{
  ...
}

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

相關(guān)文章

  • VSCode遠程代碼開發(fā)及DNS隧道端口轉(zhuǎn)發(fā)實現(xiàn)遠程辦公代碼

    VSCode遠程代碼開發(fā)及DNS隧道端口轉(zhuǎn)發(fā)實現(xiàn)遠程辦公代碼

    這篇文章主要介紹了VSCode遠程代碼開發(fā)及DNS隧道端口轉(zhuǎn)發(fā)實現(xiàn)遠程辦公,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • C++如何實現(xiàn)BitMap數(shù)據(jù)結(jié)構(gòu)

    C++如何實現(xiàn)BitMap數(shù)據(jù)結(jié)構(gòu)

    這篇文章主要介紹了C++如何實現(xiàn)BitMap數(shù)據(jù)結(jié)構(gòu),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++實現(xiàn)簡單酒店管理系統(tǒng)

    C++實現(xiàn)簡單酒店管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)簡單酒店管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++ 虛函數(shù)表圖文解析

    C++ 虛函數(shù)表圖文解析

    最近學(xué)了設(shè)計模式中的簡單工廠模式,對多態(tài)有了具體的認識。于是補了補多態(tài)、虛函數(shù)、虛函數(shù)表相關(guān)的知識,本文介紹了C++ 虛函數(shù)表,感興趣的了解一下
    2021-05-05
  • C語言中main函數(shù)兩個參數(shù)的作用

    C語言中main函數(shù)兩個參數(shù)的作用

    這篇文章主要介紹了C語言中main函數(shù)兩個參數(shù)的作用,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • C語言中如何實現(xiàn)單鏈表刪除指定結(jié)點

    C語言中如何實現(xiàn)單鏈表刪除指定結(jié)點

    這篇文章主要介紹了C語言中如何實現(xiàn)單鏈表刪除指定結(jié)點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C/C++中的OpenCV讀取視頻與調(diào)用攝像頭

    C/C++中的OpenCV讀取視頻與調(diào)用攝像頭

    這篇文章主要介紹了C/C++中的OpenCV讀取視頻與調(diào)用攝像頭,具有很好的參考價值,希望對大家有所幫助。
    2022-11-11
  • C++實現(xiàn)的分布式游戲服務(wù)端引擎KBEngine詳解

    C++實現(xiàn)的分布式游戲服務(wù)端引擎KBEngine詳解

    這篇文章主要詳細介紹了C++實現(xiàn)的分布式游戲服務(wù)端引擎KBEngine的概念以及使用方法,非常的實用,有需要的小伙伴可以參考下
    2015-03-03
  • C語言中左移和右移運算符詳細介紹

    C語言中左移和右移運算符詳細介紹

    這篇文章主要介紹了C語言中左移和右移運算符詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++與Lua協(xié)程交互的示例詳解

    C++與Lua協(xié)程交互的示例詳解

    Lua 語言不支持真正的多線程,即不支持共享內(nèi)存的搶占式線程,在執(zhí)行協(xié)程體的 Lua 腳本時,Lua 同樣可以調(diào)用 C++ 的函數(shù),本文給大家介紹了C++ 與 Lua 的協(xié)程交互,需要的朋友可以參考下
    2024-02-02

最新評論

堆龙德庆县| 晋州市| 环江| 临漳县| 修文县| 巴青县| 瑞昌市| 吴川市| 宁陵县| 丰原市| 荆门市| 文化| 遵义县| 宽甸| 桂平市| 鄂尔多斯市| 新疆| 平阳县| 汉川市| 曲松县| 漳州市| 年辖:市辖区| 广州市| 剑川县| 曲周县| 宣恩县| 乌苏市| 额尔古纳市| 都昌县| 宁阳县| 琼海市| 嘉峪关市| 盘山县| 长沙县| 靖安县| 西畴县| 凯里市| 云霄县| 兴和县| 通道| 富蕴县|