首页 > 编程 > C++ > 正文

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的私有成员数据。所以当一个函数要访问一个或多个对象的私有成员时,我们可以用友元来解决这个问题。

友元的利与弊

我们使用了友元之后,发现在设计程序的时候方便了很多。原先的那些私有成员都能轻松地被访问了。于是我们不用去写那些繁琐的成员函数,程序执行的时候也减少了函数的调用次数,提高了运行效率。

一个“好朋友”带来的是效率和方便,而一个“坏朋友”却能带来更多的麻烦。友元的存在,破坏了类的封装性。一个类出现问题,就不仅仅是由这个类本身负责了,还可能和它众多的友元有关。这无疑使得检查调试的范围突然扩大了许多,难度也陡然增加。

所以,我们在使用友元的时候,权衡使用友元的利弊,使程序达到最佳的效果。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表