本文基于《C++ Primer(第五版)》,纯属个人笔记整理。若有错误欢迎大家留言指出。

一、为什么要用友元和其缺点?

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。有时候,其他类或者函数要访问该类的非公有成员,可以令其他类或者函数成为它的友元(friend)来实现。这样做提高了程序的运行效率,但同时也坏了类的封装性和隐藏性,使得非成员函数或其他类可以访问类的私有成员。

二、友元函数

友元定义格式如下:

friend 类型 函数名(形参);

首先,友元函数可以访问类的私有成员,其本身是定义在类外的普通函数,但是友元声明只能出现在类定义的内部,同时因为,友元不是类的成员也不受它所在区域访问控制级别的约束,其出现的位置不定,即既可以出现在private下也可以在public下;其次,若类想把一个函数作为它的友元,只需增加一条以friend关键字开头的函数声明语句即可。如:

 class Sales_data
{
friend Sales_data add(const Sales_data&,const Sales_data&); //定义友元函数
......
}; /*非成员函数的声明*/
Sales_data add(const Sales_data&,const Sales_data&);

这里值得注意的几点是:

(1)友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明,如果我们希望类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门针对函数进行一次声明。为了使友元对类的用户可见,我们通常把友元的声明与类的本身放置在同一个头文件中(类的外部)。

(2)友元函数的调用与一般函数的调用方式和原理一致。

(3)类和非成员函数的声明不是必须在它们的友元声明之前。

(4)友元函数能定义在类的内部,这样的函数是隐式内联的。

三、友元类

1、类之间的友元关系

如果希望一个类可以访问另一个类的非公有成员在内的所有成员(主要是非公有的成员),可以将一个类指定为另一类的友元类。

如将类B定义为类A的友元类:

 class A
{
.......//省略其他
private:
friend class B;
};

这里使用友元类有几点要注意的:

(1)友元关系不存在传递性,即每个类负责控制自己的友元类或者友元函数

(2)友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。

(3)友元关系不能被继承。

2、成员函数作为友元

即一个类的成员函数作为另一个类的友元。此时,我们必须指出该成员函数属于哪个类。

 class A
{
.......//省略其他
private:
friend void B::add(a,b);
}

这里指明函数add是类B的成员函数。

这里有一点要注意的是 B::add必须在A类之前被声明;

Ref:

C++中友元(友元函数和友元类)的用法和功能

关于C++中的友元函数的总结

最新文章

  1. 批处理——服务器的web文件备份
  2. Excel图表的基本类型与选择
  3. mysql 索引问题
  4. STL next_permutation和prev_permutation函数
  5. SQL 执行计划(二)
  6. LeetCode : 223. Rectangle Area
  7. Codeforces Round #360 (Div. 2) E. The Values You Can Make DP
  8. compiler 学习
  9. struts2 集成webservice 的方法
  10. MySQL复制表结构,表数据。
  11. Block 进阶
  12. MapReduce 简单的全文搜索2
  13. java的finalize()方法与C++的析构函数
  14. OAuth2.0学习(1-2)OAuth2.0的一个企业级应用场景 - 新浪开放平台微博OAuth2.0认证
  15. Linux文件系统选择
  16. Java Web 禁用Cookie对Session的影响
  17. 2、jQuery的基本概念-必看-版本-入口函数- jq对象和dom对象区别
  18. 修改caffe层的一般流程
  19. maven多环境参数配置
  20. (零)SQL server安装配置

热门文章

  1. 「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
  2. Linux命令应用大词典-第2章 获取帮助
  3. ionic LoadingController 模块使用
  4. vim常用命令—撤销与反撤销
  5. LinQ to SQL 及 non-LinQ方式实现Group的Performance对比
  6. 基础数据类型-list
  7. 自测之Lesson15:TCP&UDP网络编程
  8. 自测之Lesson3:makefile
  9. 感谢信——Alpha版
  10. Pipeline组Alpha版本发布说明