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. javascript -- 事件捕获,事件冒泡

    使用js的时候,当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,单击子元素时,父元素的onclick事件也会被触发.js里称这种事件连续发生的机制为事件冒泡或者事件捕获. 为什么会 ...

  2. HTML的footer置于页面最底部的方法

    方法一:footer高度固定+绝对定位 <html> <head> <style type="text/css"> html{height:%; ...

  3. VBS 移除excel数据公式,只保留值

    如果将excel数据公式移除,只保留计算之后的值,将大大减少excel文件. 因为有上篇移除excel外部数据链接的经验,进行excel数据公式移除将快的多,方法如下. 首先我们得明白怎么手动移除ex ...

  4. JQuery------实现鼠标点击和滑动不同效果

    如图: 代码: html <ul class="price-brand-right"> @foreach (Brand item in ViewBag.Brand) { ...

  5. 剑指 offer set 26 不用加减乘除做加法

    总结 1. Leetcode 上有一道题, 是不用乘除做乘法, 那道题算是背包问题的变形 2. 不用加减乘除, 还可以用移位操作 3. 将数字转成二进制格式, 然后运用二进制亦或, 移位运算解决 3. ...

  6. THINKPHP5加载公共头部尾部模板方法

    之前在3.2中用 <include file="public/header" /> 后来发现在thinkphp5中应该这样写才行 {include file=" ...

  7. 关于recycler遇到的问题

    1.//设置recyclerView不能点击myLayoutManager.setScrollEnabled(false);class MyLayoutManager extends LinearLa ...

  8. java后台高德经纬度转地理位置信息

    import java.util.LinkedList;import java.util.List; import org.apache.http.HttpResponse;import org.ap ...

  9. Animate a custom Dialog,自定义Dialog动画

    Inside res/style.xml <style name="AppTheme" parent="android:Theme.Light" /> ...

  10. 170426、centos6.5安装 Zookeeper注册中心

    注册中心服务器(192.168.3.71)配置,安装 Zookeeper: 1. 修改操作系统的/etc/hosts 文件中添加: # zookeeper servers 192.168.3.71 r ...