C++控制对类对象私有部分的访问,在外部无法直接访问类的私有或保护成员。通常,公有类方法提供唯一的访问途径。有时这种限制太严格,不适合特定的编程问题。所以C++提供了友元这种形式,通过让函数或类成为类A的友元,可以赋予该函数或类与类A的成员函数具有相同的访问权限。

友元有3种:

(1)友元函数

(2)友元类

(3)友元成员函数

1、友元函数

将其原型放在类声明中,并加上friend关键字

如:

class Time
{
public: //友元函数
friend Time operator* (double n, const Time & t);
//重载<<操作符
friend std::ostream & operator<< (std::ostream & os, const Time & t); private:
int m_hours;
int m_minutes;
};

注意:

(1)operator*() 是在类声明中声明的,但它不是类成员函数,所以在定义函数时,不能使用Time::限定符。

(2)operator*()不是成员函数,但与成员函数的访问权限相同。

综述,类的友元函数是非成员函数,其访问权限与成员函数相同。

2、友元类

可以将类作为友元,友元类的所有方法都可以访问原始类的私有成员和保护成员。

如下 friend class Remote; 声明Remote为Tv类的友元类:

#ifndef TV_H_
#define TV_H_
//电视类
class Tv
{
public:
friend class Remote; //声明Remote类为Tv类的友元,Remote类的所有方法可以访问Tv的私有和保护成员
enum{off,on};
enum{Minval,MaxVal = 20};
Tv(int s = off,int mc = 100);
~Tv(void);
void on_off(){state = (state == on ? off: on);};
bool is_on()const{return state == on;};
bool vol_up();
bool vol_down();
void channel_up();
void channel_down();
void show_settings()const;
private:
int state;
int volume;
int maxchannel;
int channel;
}; //遥控器类
class Remote
{
public:
bool vol_up(Tv & tv){return tv.vol_up();};
bool vol_down(Tv & tv){return tv.vol_down();};
void on_off(Tv & tv){tv.on_off();};
void channel_up(Tv & tv){tv.channel_up();};
void channel_down(Tv & tv){tv.channel_down();};
void set_channel(Tv & tv, int ch){tv.channel = ch;};//友元可以访问原始类的私有成员
};
#endif

友元声明可以位于公有、私有或保护部分,其所在位置无关紧要。

3、友元成员函数

在Remote类中,只有set_channel(Tv & tv, int ch)方法直接访问Tv类的私有成员,所以可以选择只让这个方法成为类的友元,而不必让Remote整个类成为友元。不过这么做必须小心排列各种声明和定义的顺序。

让Remote::set_channel()成为Tv类的友元非方法是,在Tv类中将其声明为友元:

class Tv
{
friend void Remote::set_channel(Tv & tv, int ch);
};

C++学习笔记--友元的更多相关文章

  1. C++学习笔记之友元

    一.引言 C++控制对类对象私有部分(private)的访问,通常只能通过公有的(public)类方法去访问.但是有时候这种限制太严格,不适合特定的问题,于是C++提供了另外一种形式的访问权限:友元. ...

  2. 初探C++运算符重载学习笔记&lt;2&gt; 重载为友元函数

    初探C++运算符重载学习笔记 在上面那篇博客中,写了将运算符重载为普通函数或类的成员函数这两种情况. 以下的两种情况发生.则我们须要将运算符重载为类的友元函数 <1>成员函数不能满足要求 ...

  3. 初步C++运算符重载学习笔记&lt;3&gt; 增量递减运算符重载

    初步C++运算符重载学习笔记<1> 初探C++运算符重载学习笔记<2> 重载为友元函数     增量.减量运算符++(--)分别有两种形式:前自增++i(自减--i).后自增i ...

  4. 《C++ Primer Plus》学习笔记6

    <C++ Primer Plus>学习笔记6 第11章 使用类 <<<<<<<<<<<<<<<&l ...

  5. Day 3 学习笔记

    Day 3 学习笔记 STL 模板库 一.结构体 结构体是把你所需要的一些自定义的类型(原类型.实例(:包括函数)的集合)都放到一个变量包里. 然后这个变量包与原先的类型差不多,可以开数组,是一种数据 ...

  6. 《C++ Primer Plus》学习笔记9

    <C++ Primer Plus>学习笔记9 第15章 友元.异常和其他 <<<<<<<<<<<<<<& ...

  7. c++中的运算符重载operator1(翁恺c++公开课[30]学习笔记)

    运算符重载规则: 只有已经存在的运算符才能被重载,不能自己制造一个c++中没有的运算符进行重载 重载可以在类或枚举类型内进行,也可以是全局函数,但int.float这种已有的类型内是不被允许的 不能二 ...

  8. C++基础 学习笔记五:重载之运算符重载

    C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...

  9. Qt Creator 源码学习笔记04,多插件实现原理分析

    阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...

随机推荐

  1. 第二百五十六节,Web框架

    Web框架 Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 举例: #!/usr/bin/env python #c ...

  2. Struts框架可以支持以下哪种程序开发语言?(选择1项)

    A.C B.C++ C.Java D.C# 解答:C

  3. 收藏几个支持中文的PHP字符串截取函数

    字符串截取是一个非常常见的编程任务,而往往带中文的字符串截取会经常用到.虽然不难,但是自己写函数实现又耗费时间,这里介绍一个比较好用的字符串截取函数,能够胜任基本的需求了. <?php func ...

  4. Android使用Intent实现拨打电话的动作

    使用Intent实现打电话的动作,我们须要在 AnroidMainfest.xml中增加通话权限,打开这个文件,在application节点的前面增加以下内容 <uses-permission ...

  5. Administrator privileges required for OLE Remote Procedure Call debugging: this feature will not work..

    VC++ 6.0单步调试(F10)出现警告框: 解决方法: 右键VC++ 6.0程序图标

  6. FCN 分割网络详解

    博客来源于:https://www.cnblogs.com/gujianhan/p/6030639.html: https://blog.csdn.net/sinat_24143931/article ...

  7. 一稿设计多端适配优雅的解决方案 - rem

    规范目的 为提高前端团队开发效率,输出高质量的前端页面代码,提高UI设计还原度,特编写该规范文档.本文档如有不对或者不合适的地方请及时提出. JS代码块 (function (doc, win) { ...

  8. Centos查看系统位数方法

    方法一:file /sbin/init 方法二:file /bin/ls 我的显示是32位

  9. Unreal新建C++类或C++项目失败

    出现以下错误: ... UnrealBuildTool Exception: System.UnauthorizedAccessException.... ... 是C盘无法访问权限的错误,请参考上一 ...

  10. OSG四元数与欧拉角之间的转换

    osg::Quat HPRToQuat(double heading, double pitch, double roll) { osg::Quat q( roll, osg::Vec3d(0.0, ...