本文基于《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. 在Win10中通过命令行打开UWP应用

    近期由于需要在WinX菜单中添加几个UWP应用,但发现很难找到相应的命令行,Universal Apps 的快捷方式属性里也没有. 于是到网上搜了很久才找到一个E文的页面,试了一下确实可行,分享给大家 ...

  2. libevent学习四(Working with events)

    1.事件的分类 文件可写 文件可读 超时发生 信号发生 用户触发事件   2事件的生命周期        --非 persistent                                 ...

  3. node环境清空控制台的代码

    process.stdout.write( process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H' );

  4. 仿京东淘宝商品详情页属性选择js效果

    在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...

  5. 复合词 (Compund Word,UVa 10391)

    题目描述: 题目思路: 用map保存所有单词赋键值1,拆分单词,用map检查是否都为1,即为复合词 #include <iostream> #include <string> ...

  6. 安迪的第一个字典 (Andy's First Dictionary,UVa10815)

    题目描述: #include<iostream> #include<string> #include<set> #include<sstream> us ...

  7. 【转】: 《江湖X》开发笔谈 - 热更新框架

    前言 大家好,我们这期继续借着我们工作室正在运营的在线游戏<江湖X>来谈一下热更新机制以及我们的理解和解决方案.这里先简单的介绍一下热更新的概念,熟悉这部分的朋友可以跳过,直接看我们的方案 ...

  8. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正

    @author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...

  9. JDK源码分析:Short.java

    Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...

  10. Stunnel客户端安装和配置

    声明:本文并非原创,转自华为云帮助中心的分布式缓存服务(DCS)的用户指南. 本文以公网访问华为云分布式缓存服务的Redis缓存为示例,介绍Stunnel客户端在各操作系统下的安装和配置. Stunn ...