C++实例代码详解友元函数

目录
  • 友元概述
  • 普通全局函数作为类的友元
  • 类的某个成员函数作为另一个类的友元
  • 一个类整体作为另一个类的友元
  • 友元的注意事项
  • 封装电视机 和遥控器的类

友元函数 可以直接操作类的私有数据。

friend关键字在声明处修饰函数 那么该函数就是类的友元。

友元 不是类的一部分。

友元概述

c++允许 友元 访问 私有数据。

友元的语法:

friend关键字只出现在声明处 其他类、类成员函数、全局函数都可声明为友元 友元函数不是类的成员,不带this指针 友元函数可访问对象任意成员属性,包括私有属性。

普通全局函数作为类的友元

//房间类
class Room
{
    //将goodGayVisit作为类的友元函数
    //goodGayVisit 访问 类中所有数据 但是 它不是类的成员
    friend void goodGayVisit(Room &room);
private:
    string bedRoom;//卧室
public:
    string sittingRoom;//客厅
public:
    Room()
    {
        this->bedRoom = "卧室";
        this->sittingRoom="客厅";
    }
};
// 普通全局函数 作为 类的友元
//好基友 访问 我的房间
void goodGayVisit(Room &room)
{
    cout<<"好基友访问了你的"<<room.sittingRoom<<endl;
    cout<<"好基友访问了你的"<<room.bedRoom<<endl;//ok
}
void test01()
{
    Room myRoom;
    goodGayVisit(myRoom);
}

运行结果:

类的某个成员函数作为另一个类的友元

问题1:

问题2:

成员函数内 不能访问 Room的私有数据

最终代码:

#include <iostream>
using namespace std;
class Room;//Room向前声明
class GoodGay
{
public:
    void visit1(Room &room);//此处的Room 被上方 class Room
    void visit2(Room &room);
};
class Room
{
    //如果想方 visit2作为Room类的友元 那么Visit2就可以访问 Room的私有数据
    //一定要记得 加类作用域
    friend void GoodGay::visit2(Room &room);
private:
    string bedRoom;//卧室
public:
    string sittingRoom;//客厅
public:
    Room()
    {
        this->bedRoom = "卧室";
        this->sittingRoom="客厅";
    }
};
void GoodGay::visit1(Room &room)
{
    cout<<"好基友visit1访问了你的"<<room.sittingRoom<<endl;
    //cout<<"好基友visit1访问了你的"<<room.bedRoom<<endl;//不能访问 Room私有数据
}
void GoodGay::visit2(Room &room)
{
    cout<<"好基友visit2访问了你的"<<room.sittingRoom<<endl;
    cout<<"好基友visit2访问了你的"<<room.bedRoom<<endl;
}
int main(int argc, char *argv[])
{
    Room myRoom;
    GoodGay goodGay;
    goodGay.visit1(myRoom);//只能访问客厅
    goodGay.visit2(myRoom);//客厅 卧室 都可以访问
    return 0;
}

运行结果:

一个类整体作为另一个类的友元

一个类的所有成员函数 访问 另一个类的私有数据

#include <iostream>
using namespace std;
class Room;//Room向前声明
class GoodGay
{
public:
    void visit1(Room &room);//此处的Room 被上方 class Room
    void visit2(Room &room);
};
class Room
{
    //将GoodGay作为Room的友元
    //GoodGay 所有成员函数 都可以访问 Room私有数据
    friend class GoodGay;
private:
    string bedRoom;//卧室
public:
    string sittingRoom;//客厅
public:
    Room()
    {
        this->bedRoom = "卧室";
        this->sittingRoom="客厅";
    }
};
void GoodGay::visit1(Room &room)
{
    cout<<"好基友visit1访问了你的"<<room.sittingRoom<<endl;
    cout<<"好基友visit1访问了你的"<<room.bedRoom<<endl;
}
void GoodGay::visit2(Room &room)
{
    cout<<"好基友visit2访问了你的"<<room.sittingRoom<<endl;
    cout<<"好基友visit2访问了你的"<<room.bedRoom<<endl;
}
int main(int argc, char *argv[])
{
    Room myRoom;
    GoodGay goodGay;
    goodGay.visit1(myRoom);
    goodGay.visit2(myRoom);
    return 0;
}

运行结果:

友元的注意事项

1.友元关系不能被继承。

2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A 的朋友。

3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋 友

封装电视机 和遥控器的类

1、封装电视机的类

class TV
{
    enum{ On,Off }; //电视状态
    enum{ minVol,maxVol = 100 }; //音量从0到100
    enum{ minChannel = 1,maxChannel = 255 }; //频道从1到255
private:
    int mState; //电视状态,开机,还是关机
    int mVolume; //电视机音量
    int mChannel; //电视频道
public:
    TV()
    {
        this->mState = Off;//默认关机
        this->mVolume = minVol;
        this->mChannel = minChannel;
    }
    void onOrOff(void)
    {
        this->mState = (this->mState == On ? Off:On);
    }
    //加大音量
    void volumeUp(void)
    {
        if(this->mVolume >= maxVol)
            return;
        this->mVolume++;
    }
    //减小音量
    void volumeDown(void)
    {
        if(this->mVolume <= minVol)
            return;
        this->mVolume--;
    }
    //增加频道
    void channelUp(void)
    {
        if(this->mChannel >= maxChannel)
            return;
        this->mChannel++;
    }
    //减小频道
    void channelDown(void)
    {
        if(this->mChannel <= minChannel)
            return;
        this->mChannel--;
    }
    //显示电视机的状态
    void showTVState(void)
    {
        cout<<"电视机的状态为:"<< (this->mState==On ? "开机":"关机") <<endl;
        cout<<"电视机的音量:"<<this->mVolume<<endl;
        cout<<"电视机的频道:"<<this->mChannel<<endl;
    }
};
void test01()
{
    TV tv;
    tv.onOrOff();//开机
    tv.volumeUp();//调四次音量
    tv.volumeUp();
    tv.volumeUp();
    tv.volumeUp();
    tv.channelUp();//调三次频道
    tv.channelUp();
    tv.showTVState();
}

运行结果:

2、设置遥控器的类2-1

class TV
{
    friend class Remote;
    //默认为私有
    enum{ On,Off }; //电视状态
    enum{ minVol,maxVol = 100 }; //音量从0到100
    enum{ minChannel = 1,maxChannel = 255 }; //频道从1到255
private:
    int mState; //电视状态,开机,还是关机
    int mVolume; //电视机音量
    int mChannel; //电视频道
public:
    TV()
    {
        this->mState = Off;//默认关机
        this->mVolume = minVol;
        this->mChannel = minChannel;
    }
    void onOrOff(void)
    {
        this->mState = (this->mState == On ? Off:On);
    }
    //加大音量
    void volumeUp(void)
    {
        if(this->mVolume >= maxVol)
            return;
        this->mVolume++;
    }
    //减小音量
    void volumeDown(void)
    {
        if(this->mVolume <= minVol)
            return;
        this->mVolume--;
    }
    //增加频道
    void channelUp(void)
    {
        if(this->mChannel >= maxChannel)
            return;
        this->mChannel++;
    }
    //减小频道
    void channelDown(void)
    {
        if(this->mChannel <= minChannel)
            return;
        this->mChannel--;
    }
    //显示电视机的状态
    void showTVState(void)
    {
        cout<<"电视机的状态为:"<< (this->mState==On ? "开机":"关机") <<endl;
        cout<<"电视机的音量:"<<this->mVolume<<endl;
        cout<<"电视机的频道:"<<this->mChannel<<endl;
    }
};
//遥控器类
class Remote
{
private:
    TV *pTv;
public:
    Remote(TV *pTv)
    {
        this->pTv = pTv;
    }
    //音量的加减
    void volumeUp(void)
    {
        //调节的电视机的音量
        this->pTv->volumeUp();
    }
    void volumeDown(void)
    {
        this->pTv->volumeDown();
    }
    //频道的加减
    void channelUp(void)
    {
        this->pTv->channelUp();
    }
    void channelDown(void)
    {
        this->pTv->channelDown();
    }
    //电视开关
    void onOrOff(void)
    {
        this->pTv->onOrOff();
    }
    //遥控器设置频道设置
    void setChannel(int num)
    {
        //判断 频道 是否有效
        if(num >= TV::minChannel && num<= TV::maxChannel )
        {
            this->pTv->mChannel = num;
        }
    }
    void showTVState(void)
    {
        this->pTv->showTVState();
    }
};
void test02()
{
    TV tv;
    Remote remote(&tv);
    remote.onOrOff();
    remote.volumeUp();
    remote.volumeUp();
    remote.volumeUp();
    remote.volumeUp();
    remote.channelUp();
    remote.channelUp();
    remote.showTVState();
    remote.setChannel(75);
    remote.showTVState();
}

运行结果:

到此这篇关于C++实例代码详解友元函数的文章就介绍到这了,更多相关C++友元函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++简单又轻松的讲解类和对象中友元函数

    目录 友元 浅解概念 友元目的 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 注意事项 总结 友元 用到关键字 friend 浅解概念 举一个非常实际的例子,假如端午节到了你煮了两种粽子,一种是普通的糯米粽子,一种是特殊的五花肉粽子,糯米粽只要是客人都可以品尝,而五花肉棕只限好朋友品尝,这时候就可以用到友元的知识了.在程序里,有些私有属性也想让类外特殊的一些函数或者类访问,就要用到友元函数. 友元目的 让一个函数或者类,访问另一个类的私有属性 友元的三种实现 全局函数.成员函数.类都

  • C++友元函数与拷贝构造函数详解

    一.友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数. 友元函数和普通函数的定义一样;在类内必须将该普通函数声明为友元. (2)友元函数不是成员函数. 不能通过对象来调用,而是直接调用;友元函数可以访问类的公有.受保护以及私有成员,但是必须通过对象.对象指针或者对象引用来访问. 2.友元函数的声明: friend 返回值类型 函数名(参数表); 在类中只需要将这个声明放置在公有部分即可. class Point { double x, y; public: Point(){

  • 在C++中关于友元函数的进一步理解

    这里重新将类的成员函数的定义看一下: 百科上的认识: 类的成员函数的原型要写在类体中,原型说明了函数的参数表和返回值类型.而函数的定义一般在类外面,也可以直接在类内部定义.前者与普通函数不同的是,实现成员函数时要指明类的名称,具体形式为: 返回值类型 类名 :函数成员名(参数表){函数体}: 而后者一般为一些短小的函数(5行以内),也就是内联函数. 这里在百科上对友元函数的解释: 友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数.类授予它的友元特别的访问权.通常同一个开发者会出于技术和

  • C++中友元函数(friend)解析

     文章转自公众号:Coder梁(ID:Coder_LT) 我们知道C++控制对象的私有部分的访问,只能通过公共的接口.这样的设计当然没错,但有的时候也会显得过于严格,产生一些问题. 因此C++提供了另外一种形式的访问权限,叫做友元(friend). 友元有三种,分别是友元函数.友元类和友元成员函数. 通过让函数成为类的友元,可以赋予该函数与类成员函数一样的访问权限,也就是说我们可以在友元函数当中访问类的私有成员变量. 在介绍友元函数的使用之前,我们需要先了解为什么需要友元函数.C++ Prime

  • C++ 中友元函数与友元类详解

    C++ 中友元函数与友元类详解 总的来说,友元分为两类:友元函数与友元类.友元是针对类而言,它提供了一种非类的成员函数来访问类的非公有成员的一种机制.可以把一个函数指定为某类的友元,这个函数称为这个类的友元函数.也可以将类A指定为类B的友元,则类A是类B的友元类,类A的所有成员函数均是类B的友元函数,均可以访问类B的非公有成员.        友元函数的注意事项: (1)友元函数不是类的成员函数,在函数体中访问对象的成员,必须用"对象名.对象成员"方式来访问, 友元函数可以访问类中的所

  • C++中成员函数和友元函数的使用及区别详解

    为什么使用成员函数和友元函数 这个问题至关重要,直接影响着后面的理解: 程序数据: 数据是程序的信息,会受到程序函数的影响.封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全. 数据封装引申出了另一个重要的 OOP 概念,即 数据隐藏 .数据封装 是一种把数据和操作数据的函数捆绑在一起的机制, 数据抽象 是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制.C++ 通过创建类来支持封装和数据隐藏(public.protected.p

  • 关于C++友元函数的实现讲解

    友元函数是一种特殊的函数,它必须要在类中进行声明,但其本身并不是类的成员函数,但友元函数可以访问类的私有成员变量. 友元函数的好处: 1.实现类之间的数据共享 2.提高程序运行效率,方便编程 友元函数的坏处: 1.破坏数据的隐蔽性和类的封装性 2.降低了程序的可维护性 所有,友元函数应当谨慎的去使用它. 实例: #include <iostream> #include <cstring> using namespace std ; class Student { private :

  • 简要介绍C++编程中的友元函数和友元类

    一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员.现在,我们来补充介绍一个例外--友元(friend). fnend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些.有的家庭可能会这样处理:客厅对所有来客开放,而卧室除了本家庭的成员可以进人以外,还允许好朋友进入.在C++中,这种关系以关键宇 friend 声明,中文多译为友元.友元可以访问与其有好友关系的类

  • C++中的友元函数与友元类详情

    目录 一.问题背景 二.友元函数 三.友元类 一.问题背景 对类的封装是C++三大特性中的一个重要特性,封装好的数据在类的外部是访问不到的但是一旦出了问题,想要操作被封装的数据怎么办呢?由此友元函数友元类诞生了.在类中用friend关键字声明的函数或类,可以对类体中的任何权限成员属性进行操作有好处就有坏处友元函数.友元类严重破坏类的封装性,不到迫不得已不要使用. 二.友元函数 声明部分: friend 返回类型 函数名 (参数列表); 定义部分:返回类型 函数名 (参数列表){        函

  • C++实例代码详解友元函数

    目录 友元概述 普通全局函数作为类的友元 类的某个成员函数作为另一个类的友元 一个类整体作为另一个类的友元 友元的注意事项 封装电视机 和遥控器的类 友元函数 可以直接操作类的私有数据. friend关键字在声明处修饰函数 那么该函数就是类的友元. 友元 不是类的一部分. 友元概述 c++允许 友元 访问 私有数据. 友元的语法: friend关键字只出现在声明处 其他类.类成员函数.全局函数都可声明为友元 友元函数不是类的成员,不带this指针 友元函数可访问对象任意成员属性,包括私有属性.

  • Java回调函数实例代码详解

    首先说说什么叫回调函数? 在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调.在调用接口时,需要严格的按照定义的参数和方法调用,并且需要处理函数的异步,否则会导致程序的崩溃. 这样的解释似乎还是比较难懂,这里举个简 单的例子: 程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序.程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法.目的达到

  • javascript中函数的写法实例代码详解

    具体代码如下所述: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible

  • C++ 基础教程之虚函数实例代码详解

    虚函数的定义 虚函数:就是在基类的成员函数前加关键字virtual(即被virtual关键字修饰的成员函数),并在一个或多个派生类中被重新定义的成员函数:虚函数:就是在编译的时候不确定要调用哪个函数,而是动态决定将要调用哪个函数.它的作用就是为了能让这个函数在它的子类里面可以被重载,这样的话,编译器就可以使用后期绑定来达到多态了,也就是用基类的指针来调用子类的这个函数:虚函数的作用:在于用专业术语来解释就是实现多态性,多态性是将接口与实现进行分离,通过指向派生类的基类指针或引用,访问派生类中同名

  • jQuery fadeOut 异步实例代码详解

    定义和用法 fadeOut() 方法逐渐改变被选元素的不透明度,从可见到隐藏(褪色效果). 注释:隐藏的元素不会被完全显示(不再影响页面的布局). 提示:该方法通常与 fadeIn() 方法一起使用. 语法 $(selector).fadeOut(speed,easing,callback) 1. 概述 jquery实现动画效果的函数使用起来很方便,不过动画执行是异步的,所以要把自定义的操作放在回调函数里. 2. example <html> <body> <table id

  • jQuery Ajax 全局调用封装实例代码详解

    有一种情况:全站都要用异步方式来调用 数据,提交数据,那么你每次操作 都会要$.ajax({.....}) 写重复的方法 和代码,冗余太大, 也浪费时间,虽说你有代码自动提示补全,但真的不优雅,身为前端极客,是不能允许的! [嘿嘿!虽说我现在基本不用jquery了 ,不过异步概念 是永远要用的,就帮助下新人] jQuery Ajax通用js封装 第一步:引入jQuery库 <script type="text/javascript" src="/js/jquery.mi

  • JS动画实现回调地狱promise的实例代码详解

    1. js实现动画 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>animate</title> <style> .ball { width: 40px; height: 40px; margin-bottom: 5px; border-radius: 20px; } .ball1 { ba

  • 使用Vue.observable()进行状态管理的实例代码详解

    随着组件的细化,就会遇到多组件状态共享的情况, Vuex当然可以解决这类问题,不过就像 Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是 vue.js 2.6 新增加的 Observable API ,通过使用这个 api 我们可以应对一些简单的跨组件数据状态共享的情况. 先看下官网描述,如下图 observable()方法,用于设置监控属性,这样就可以监控viewModule中的属性值的变化,从而就可以动态的改变某个元素中的值,监控属性的类型不变量而

  • vue实现绑定事件的方法实例代码详解

    一.前言 vuejs中的事件绑定,使用<v-on:事件名 = 函数名>来完成的,这里函数名是定义在Vue实例中的methods对象中的,Vue实例可以直接访问其中的方法. 二.事件绑定方式 1. 直接在标签中写js方法  <button v-on:click="alert('hi')">执行方法的第一种写法</button> 2.调用method的办法 <button v-on:click="run()">执行方法的第

  • vue中使用mxgraph的方法实例代码详解

    1.npm 引入 npm install mxgraph --save 2.这个模块可以使用require()方法进行加载.它将返回一个接受对象作为选项的工厂函数.必须将mxBasePath选项提供给工厂函数,而不是将其定义为一个全局变量. var mxgraph = require("mxgraph")( { // 以下地址不需要修改 mxImageBasePath: "./src/images", mxBasePath: "./src" })

随机推荐