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. C++ 运算符重载三(链式编程)

    //运算符重载之链式编程 #include<iostream> using namespace std; //对于友元函数重载运算符只适用于左操作数是系统变量的场景 //因为成员无法在系统 ...

  2. i2c 异常之i2c1 prob 检测超时

    在没加atl 的fpga 时 i2c1上的tvp5150 vpss驱动加载没问题, 加了之后出现超时 I2C: timed out in wait_for_bb: I2C_IRQSTATUS=1000 ...

  3. Fragment遇到的坑

    Fragment不要通过构造传参,要么就是bundle,要么就通过activity临时存一下,不然debug编译没问题release编译不过

  4. php 重写session

    重写session的存储机制 转自 http://www.cnblogs.com/bc8web/p/5699935.html Session数据区 默认以 文件的形式存储与服务器操作系统临时目录中! ...

  5. 将UIView转成UIImage,将UIImage转成PNG/JPG

    分类: UIImageView2013-03-12 17:37 350人阅读 评论(0) 收藏 举报 //UIView -> UIImage #import “QuartzCore/Quartz ...

  6. 在 Ubuntu Mate 16.04 上通过 PPA 升级 Mate 1.14

    导读 Mate 桌面环境 1.14 现在可以在 Ubuntu Mate 16.04 ("Xenial Xerus") 上使用了.根据这个版本的描述,为了全面测试 Mate 1.14 ...

  7. visual studio 常识

    去掉 引用提示 文本编辑器=>所有语言=>codelens

  8. Android 全局异常处理(三)

    用过安卓手机的用户以及安卓开发者们会时长碰到程序异常退出的情况,普通用户遇到这种情况,肯定非常恼火,甚至会骂一生垃圾软件,然后卸载掉.那么开发者们在开发过程中遇到这种情况给怎么办呢,当然,你不可能世界 ...

  9. PAT 甲级 1068 Find More Coins(0,1背包)

    1068. Find More Coins (30) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Eva l ...

  10. oracle导入TXT文件

    oracle导入TXT文件: 1.建好对应的表和字段:2.新建test.ctl文件,用记事本编辑写入: OPTIONS (skip) load data INFILE 'E:\8080.txt' -- ...