国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

C++教程:C++友元類講解

2020-05-23 14:25:46
字體:
供稿:網(wǎng)友
在編寫鏈表類的時候我們有著這樣的困惑:鏈表類和鏈表結(jié)點類都是我們編寫的,我們能保證鏈表類對鏈表結(jié)點類的操作都是安全的。但由于類的封裝性,我們不得不編寫一些成員函數(shù),以便于鏈表類訪問鏈表結(jié)點類的私有成員數(shù)據(jù)。好在鏈表結(jié)點類的成員數(shù)據(jù)并不是很多,否則豈不是需要一大堆成員函數(shù)來供別的類訪問?對于這種情況,我們能否告訴鏈表結(jié)點類:“鏈表類是安全的,讓它訪問你的私有成員吧”?

在C++中,可以用友元來解決這種尷尬的問題。所謂友元,就是作為一個類的“朋友”,可以例外地訪問它的私有成員數(shù)據(jù)或私有成員函數(shù)。

友元類

類似于鏈表類和鏈表結(jié)點類的問題,我們可以用友元類來解決。即鏈表類是鏈表結(jié)點類的“朋友”,可以直接訪問鏈表結(jié)點類的私有成員數(shù)據(jù)或私有成員函數(shù)。顯然,要做鏈表結(jié)點類的“朋友”,必須要得到鏈表結(jié)點類的認可。所以我們必須在鏈表結(jié)點類的聲明中告訴電腦,鏈表類是它認可的“朋友”,可以訪問它的私有成員。聲明友元類的語句格式為:
    friend class 類名;
下面我們來看一下,友元是如何讓我們更方便地設(shè)計程序的:(程序16.2.1)
//node.h
class Node//聲明一個鏈表結(jié)點類
{
   friend class Linklist;//在Node類中聲明友元類Linklist
   public:
   Node();
   Node(Node &n);
   Node(int i,char c='0');
   Node(int i,char c,Node *p,Node *n);
   ~Node();
   static int allocation();
   private:
   int idata;
   char cdata;
   Node *prior;
   Node *next;
   static int count;
};
//node.cpp
#include "node.h"
#include <iostream>
using namespace std;
int Node::count=0;
Node::Node()
{
   cout <<"Node constructor is running..." <<endl;
   count++;
   idata=0;
   cdata='0';
   prior=NULL;
   next=NULL;
}
Node::Node(int i,char c)
{
   cout <<"Node constructor is running..." <<endl;
   count++;
   idata=i;
   cdata=c;
   prior=NULL;
   next=NULL;
}
Node::Node(int i,char c,Node *p,Node *n)
{
   cout <<"Node constructor is running..." <<endl;
   count++;
   idata=i;
   cdata=c;
   prior=p;
   next=n;
}
Node::Node(Node &n)
{
   count++;
   idata=n.idata;
   cdata=n.cdata;
   prior=n.prior;
   next=n.next;
}
Node::~Node()
{
   count--;
   cout <<"Node destructor is running..." <<endl;
}
int Node::allocation()
{
   return count;
}
//linklist.h
#include "node.h"
#include <iostream>
using namespace std;
class Linklist//定義一個鏈表類
{
   public:
   Linklist(int i,char c);
   Linklist(Linklist &l);
   ~Linklist();
   bool Locate(int i);
   bool Locate(char c);
   bool Insert(int i=0,char c='0');
   bool Delete();
   void Show();
   void Destroy();
   private:
   Node head;
   Node * pcurrent;
};
Linklist::Linklist(int i,char c):head(i,c)//鏈表的構(gòu)造函數(shù)
{
   cout<<"Linklist constructor is running..."<<endl;
   pcurrent=&head;
}
Linklist::Linklist(Linklist &l):head(l.head)
{
   cout<<"Linklist Deep cloner running..." <<endl;
   pcurrent=&head;
   Node * ptemp1=l.head.next;//直接訪問私有成員數(shù)據(jù)
   while(ptemp1!=NULL)
   {
      Node * ptemp2=new Node(ptemp1->idata,ptemp1->cdata,pcurrent,NULL);
      pcurrent->next=ptemp2;
      pcurrent=pcurrent->next;
      ptemp1=ptemp1->next;
}
}
Linklist::~Linklist()
{
   cout<<"Linklist destructor is running..."<<endl;
   Destroy();
}
bool Linklist::Locate(int i)
{
   Node * ptemp=&head;
   while(ptemp!=NULL)
   {
      if(ptemp->idata==i)
      {
         pcurrent=ptemp;
         return true;
      }
      ptemp=ptemp->next;
   }
   return false;
}
bool Linklist::Locate(char c)
{
   Node * ptemp=&head;
   while(ptemp!=NULL)
   {
      if(ptemp->cdata==c)
      {
         pcurrent=ptemp;
         return true;
      }
      ptemp=ptemp->next;
   }
   return false;
}
bool Linklist::Insert(int i,char c)
{
   if(pcurrent!=NULL)
   {
      Node * temp=new Node(i,c,pcurrent,pcurrent->next);
      if (pcurrent->next!=NULL)
      {
         pcurrent->next->prior=temp;
      }
      pcurrent->next=temp;
      return true;
   }
   else
   {
      return false;
   }
}
bool Linklist::Delete()
{
   if(pcurrent!=NULL && pcurrent!=&head)
   {
      Node * temp=pcurrent;
      if (temp->next!=NULL)
      {
         temp->next->prior=pcurrent->prior;
      }
      temp->prior->next=pcurrent->next;
      pcurrent=temp->prior;
      delete temp;
      return true;
   }
   else
   {
      return false;
   }
}
void Linklist::Show()
{
   Node * ptemp=&head;
   while (ptemp!=NULL)
   {
      cout <<ptemp->idata <<'/t' <<ptemp->cdata <<endl;
      ptemp=ptemp->next;
   }
}
void Linklist::Destroy()
{
   Node * ptemp1=head.next;
   while (ptemp1!=NULL)
   {
      Node * ptemp2=ptemp1->next;
      delete ptemp1;
      ptemp1=ptemp2;
   }
   head.next=NULL;
}
//main.cpp同程序16.1

運行結(jié)果:
請輸入一個整數(shù)和一個字符:
3 F
Node constructor is running...
Linklist constructor is running...
Node constructor is running...
Node constructor is running...
After Insert
3 F
2 B
1 C
Node Allocation:3
Node constructor is running...
An independent node created
Node Allocation:4
Node destructor is running...
Linklist destructor is running...
Node destructor is running...
Node destructor is running...
Node destructor is running...

可以看到,程序的運行結(jié)果和程序16.1的結(jié)果一樣,但是鏈表結(jié)點類沒有程序16.1中那么繁瑣。并且在鏈表類中完全都是直接訪問鏈表結(jié)點類的成員數(shù)據(jù),大大減少了調(diào)用函數(shù)產(chǎn)生的開銷,這樣執(zhí)行程序的效率也就得以提高了。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 改则县| 凯里市| 神木县| 韶山市| 前郭尔| 应城市| 治多县| 峡江县| 裕民县| 鄢陵县| 惠州市| 百色市| 嵩明县| 葵青区| 阜新| 高碑店市| 绥中县| 阳曲县| 郸城县| 阿城市| 夏河县| 定陶县| 凉山| 平潭县| 仙桃市| 托里县| 开鲁县| 亚东县| 克什克腾旗| 麻阳| 香港 | 上高县| 永昌县| 济宁市| 高陵县| 九江市| 盘山县| 新津县| 正蓝旗| 卢氏县| 凤台县|