C++教程:C++友元函數講解
2020-05-23 14:25:42
供稿:網友
私有成員數據除了可能被別的類訪問之外,也可能被別的函數或別的類的部分成員函數訪問。為了保證類的封裝性,我們可以以函數作為單位,“對外開放”類的私有成員。與聲明友元類類似,如果我們想用函數訪問鏈表結點類的私有成員數據,則那些函數必須得到鏈表結點類的認可。聲明友元函數的語句格式為:
friend 返回值類型函數名(參數表);
如果該函數是某個類的成員函數,則語句格式為:
friend 返回值類型類名::函數名(參數表);
需要注意的是,在聲明友元成員函數時,可能會牽扯出一系列的類的聲明順序問題。當類的結構本身就比較復雜時,友元的使用可能會使得這個問題愈加突出。
下面我們就用友元函數來輸出一個結點的信息:(程序16.2.2)
//node.h
class Node
{
friend class Linklist; //在Node類中聲明友元類Linklist
friend void ShowNode(Node &n);//聲明友元函數ShowNode
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
//其余部分同程序16.2.1
void ShowNode(Node &n)
{
cout <<n.idata <<'/t' <<n.cdata <<endl;//友元函數可以訪問私有成員數據
}
//linklist.h同程序16.2.1
//main.cpp
#include <iostream>
#include "Linklist.h"
using namespace std;
int main()
{
int tempi;
char tempc;
cout <<"請輸入一個整數和一個字符:" <<endl;
cin >>tempi >>tempc;
Linklist a(tempi,tempc);
a.Locate(tempi);
a.Insert(1,'C');
a.Insert(2,'B');
cout <<"After Insert" <<endl;
a.Show();
Node b(4,'F');
cout <<"An independent node created" <<endl;
cout <<"Use friend function to show node" <<endl;
ShowNode(b);//用友元函數輸出b結點的內容
return 0;
}
運行結果:
請輸入一個整數和一個字符:
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 constructor is running...
An independent node created
Use friend function to show node
4 G
Node destructor is running...
Linklist destructor is running...
Node destructor is running...
Node destructor is running...
Node destructor is running...
我們看到函數ShowNode成功地訪問了鏈表結點b的私有成員數據。所以當一個函數要訪問一個或多個對象的私有成員時,我們可以用友元來解決這個問題。
友元的利與弊
我們使用了友元之后,發現在設計程序的時候方便了很多。原先的那些私有成員都能輕松地被訪問了。于是我們不用去寫那些繁瑣的成員函數,程序執行的時候也減少了函數的調用次數,提高了運行效率。
一個“好朋友”帶來的是效率和方便,而一個“壞朋友”卻能帶來更多的麻煩。友元的存在,破壞了類的封裝性。一個類出現問題,就不僅僅是由這個類本身負責了,還可能和它眾多的友元有關。這無疑使得檢查調試的范圍突然擴大了許多,難度也陡然增加。
所以,我們在使用友元的時候,權衡使用友元的利弊,使程序達到最佳的效果。