zoukankan      html  css  js  c++  java
  • 友元函数

    -----------------siwuxie095

       

       

       

       

       

       

       

       

    C++ 中,存在着一种朋友关系,这种朋友关系如果体现在函数上,

    就称之为 友元函数,如果体现在类上,就称之为 友元类

       

       

       

    这里介绍 友元函数

       

       

       

       

    友元函数

       

       

    就定义函数的情形来说,一种是将其定义为全局函数,另一种

    是将其定义在类中,使它成为类的成员函数

       

       

       

       

    当把全局函数声明为友元函数,就称之为 友元全局函数,当把

    成员函数声明为另一个类的友元函数,就称之为 友元成员函数

       

       

       

       

       

       

       

       

    友元全局函数

       

       

    看如下实例:

       

    定义一个坐标类:Coordinate

       

       

       

       

    如果想要定义一个友元函数,就要使用关键字:friend

       

    使用方法:通过关键字 friend 接友元函数

       

    友元函数其实就是一个函数的声明,声明的最后以分号结尾,同时一定

    要传入当前类的对象 或引用 或指针,总之,要能通过该函数访问到对象

    中私有的数据成员 保护的数据成员

       

       

       

    友元函数的使用方法:

       

       

       

    printXY() 即 打印横纵坐标,需要传入一个 Coordinate 的引用,

    访问时,可以直接访问私有数据成员

       

    如果没有将 printXY() 声明为 Coordinate 的友元,那么直接访

    问私有数据成员,编译器就会报错

       

    注意:传入引用 指针,传递效率更高,执行速度更快,提倡

    传入 引用 指针,而不提倡直接传入 对象

       

       

    main() 函数中调用 printXY() 时,需要先实例化一个 Coordinate

    的对象,然后将该对象传递进去即可

       

       

       

       

    友元成员函数

       

       

    看如下实例:

       

       

       

    此时仍然使用关键字:friend,但注意后面的写法:

       

    使用的函数仍然是 printXY(),但此时 printXY() 并不是一个全局函数,

    而是 Circle 类中的成员函数,如果要将 Circle 类的 printXY() 声明为

    Coordinate 类的友元函数,需要将 Circle 写出来,后面接 ::,后面再

    接 printXY()

       

       

       

    在使用时:

       

    Circle 类中 printXY() 的实现方法和前面的实现方法基本相同

       

       

       

       

    友元给我们带来方便的同时,也带来了一些风险:

       

    当在 Coordinate 类中将 Circle 类的 printXY() 声明为它的友元之后,

    也就破坏了 Coordinate 类的封装性。破坏了封装性之后,对于数据

    的直接访问虽然是方便了,但是如果不小心改变了数据的值,也不易

    察觉

       

    所以,风险和方便往往是相互矛盾的。除非有特殊的需要,否则一般

    情况下,不建议处处使用友元,把友元当做自己知识的一种炫耀

       

       

       

       

       

    程序:

       

       

    Match.h:

       

    #ifndef MATCH_H

    #define MATCH_H

       

    #include <iostream>

    using namespace std;

       

       

    class Time;//注意这里要声明

    class Match

    {

    public:

    //声明printTime2()时要用到 Time

    //所以必须要在 Match 的上面通过 Time 声明一下,

    //有这样一个类,后面的时候会定义

    void printTime2(Time &t);

    };

       

    #endif

       

       

       

    Match.cpp:

       

    #include "Match.h"

    #include "Time.h"

       

    void Match::printTime2(Time &t)

    {

    cout << t.m_iHour << ":" << t.m_iMinute << ":" << t.m_iSecond << endl;

    }

       

       

       

    Time.h:

       

    #ifndef TIME_H

    #define TIME_H

       

    #include "Match.h"//这里要加上Match的头文件

    #include <iostream>

    using namespace std;

       

       

    class Time

    {

    //作为友元函数来说,位置并没有约束,写在哪里都行,

    // friend 的友元声明,与访问限定符并不形成交叉关系

    //

    //建议写在类的最前边,因为对于类来说,对外如何进行暴露是非常重要的

    //把重要的信息放在前边有助于编程过程中减小犯错的概率

    friend void printTime1(Time &t);//友元全局函数

    friend void Match::printTime2(Time &t);//友元成员函数

       

    public:

    Time(int hour, int min, int sec);

    private:

    int m_iHour;

    int m_iMinute;

    int m_iSecond;

    };

       

    #endif

       

       

       

    Time.cpp:

       

    #include "Time.h"

       

    Time::Time(int hour, int min, int sec)

    {

    m_iHour = hour;

    m_iMinute = min;

    m_iSecond = sec;

    }

       

       

       

    main.cpp:

       

    #include "stdlib.h"

    #include "Time.h"

    #include "Match.h"

       

    //提倡把函数的声明写在前面,定义写在后面

    void printTime1(Time &t);

       

    int main(void)

    {

    Time t(6, 34, 25);

    printTime1(t);

    Match m;

    m.printTime2(t);

    system("pause");

    return 0;

    }

       

    //通过声明友元,就能使得传入进来的对象

    //去访问它私有的数据成员和成员函数

    void printTime1(Time &t)

    {

    cout << t.m_iHour << ":" << t.m_iMinute << ":" << t.m_iSecond << endl;

    }

       

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    Wireshark抓取网站用户名密码
    为ctf而生的web扫描器ctf-wscan
    windows下pip安装python模块时报错总结
    火绒剑获取IP位置
    shodan 搜寻公共摄像头
    肥猪流码农的逆袭之路(1)
    如何备份centos系统
    centos下nginx搭建drupal 8
    openstack学习笔记9-selfservice网络配置
    术语解释-什么是Overlay Network和Underlay Network
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6813813.html
Copyright © 2011-2022 走看看