本文基于《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++中的友元函数的总结

C++中友元简介的更多相关文章

  1. [置顶] c++,vc6.0,中友元函数,无法访问私有字段(private)的问题(problem),cannot access private member declared in class 'Date'

    c++,vc6.0,中友元函数,无法访问私有字段(private)的问题(problem),cannot access private member declared in class 'Date' ...

  2. Spring中AOP简介与切面编程的使用

    Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...

  3. SpringMVC 中HttpMessageConverter简介和Http请求415 Unsupported Media Type的问题

    一.概述: 本文介绍且记录如何解决在SpringMVC 中遇到415 Unsupported Media Type 的问题,并且顺便介绍Spring MVC的HTTP请求信息转换器HttpMessag ...

  4. C++中const简介及用法

    1.const简介 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰 ...

  5. gcc的bug? c++模板类中友元函数的訪问权限问题

    原文地址:http://stackoverflow.com/q/23171337/3309790 在c++中,模板类中能够直接定义一个友元函数.该函数拥有訪问该模板类非public成员的权限. 比方: ...

  6. C++中友元

    一.友元分为两种 1.友元函数 2.友元类 二.解析比较好的博客:http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/04/2535305.htm ...

  7. C++中友元详解

    问题的提出 我们已知道类具备封装和信息隐 藏的特性.只有类的成员函数才能访问类的私有成员,程式中的其他函数是无法访问私有成员的.非成员函数能够访问类中的公有成员,但是假如将数据成员都定义 为公有的,这 ...

  8. C++模板类中友元函数的写法

    首先,已声明好的类Triangle file://Triangle.h template<class T> class Triangle{ public: Triangle(T width ...

  9. Django中ORM简介与单表数据操作

    一. ORM简介  概念:.ORM框架是用于实现面向对象编程语言种不同类型系统的数据之间的转换 构建模型的步骤:重点 (1).配置目标数据库信息,在seting.py中设置数据库信息 DATABASE ...

随机推荐

  1. hadoop 家族图

    hadoop家族

  2. Python 通过sgmllib模块解析HTML

    """ 对html文本的解析方案-示例:在标签开始的时候检查标签中的attrs属性,解析出所有的参数的href属性值 依赖安装:pip install sgmllib3k ...

  3. selenium元素定位(三)

    使用selenium就不可避免的要提到界面元素定位,通过元素定位来实现一系列的逻辑操作. selenium提供了8中元素定位的方式: id.name.class name.tag name.link ...

  4. Unity初探之黑暗之光(1)

    Unity初探之黑暗之光(1) 1.镜头拉近 public float speed=10f;//镜头的移动速度 ;//镜头的结束位置 // Update is called once per fram ...

  5. spring boot 报错 Error creating bean with name

    Application 启动类 要和父目录平级

  6. node包管理相关

    切换npm数据源 镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set registry https ...

  7. 硬件原理图Checklist检查表(通用版)

    类别 描述 检视规则 原理图需要进行检视,提交集体检视是需要完成自检,确保没有低级问题. 检视规则 原理图要和公司团队和可以邀请的专家一起进行检视. 检视规则 第一次原理图发出进行集体检视后所有的修改 ...

  8. android仿美团客户端购买框悬浮特效

        实现步骤如下: 1,新建一个项目,新建一个MyScrollView继承自ScrollView   public class MyScrollView extends ScrollView { ...

  9. Alpha 冲刺2

    队名:日不落战队 安琪(队长) 今天完成的任务 组织第二次站立式会议. 完成40%个人信息前端界面. 明天的计划 完成剩下的60%个人信息前端界面. 还剩下的任务 个人信息修改前端界面. 遇到的困难 ...

  10. LintCode-71.二叉树的锯齿形层次遍历

    二叉树的锯齿形层次遍历 给出一棵二叉树,返回其节点值的锯齿形层次遍历(先从左往右,下一层再从右往左,层与层之间交替进行) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, 返回其锯齿形的层次 ...