• C++_友元3-其他友元关系


    友元和类的关系还可以更复杂。

    举个例子,假设出现了交互式遥控器,交互式遥控器能够让您回答电视节目中的问题,如果回答错误,电视将在控制器上产生嗡嗡声。

    这个例子的问题,可以使用新的友元关系来解决。我把它叫做相互的友情。

    即一些Remote方法能够像前面那样访问Tv对象,而一些Tv方法也能影响Remote对象。

    这可以通过让类彼此成为对方的友元来实现。即相互的友元

    即除了Remote是Tv的友元外,Tv还是Remote的友元。

    这里对于使用Remote对象的Tv方法,其原型可以再Remote方法类声明之前声明,但必须在Remote声之后定义,以便编译器有足够的信息来编译该方法。

    方法如下:(两个类互为友元类)

    class Tv

    {

    friend class Remote;

    public:

      void buzz(Remote & r);

      ...

    };

    class Remote

    {

    friend class Tv;

    public:

      void Bool volup(Tv & t) {t.volup();}

    }

    //buzz方法的声明和定义是分开的,定义要在Remote声明之后,这是因为这个时候编译器编译该方法时,知道Remote指的是什么了;

    inline void Tv::buzz(Remote & r)

    {

    ...

    }

    还有一种友元的情况是共同的友元

    需要使用友元的另一种情况是,函数需要访问两个类的私有数据。

    从逻辑上看,这样的函数时每个类的成员函数,但是这是不可能的。

    它可以是一个类的成员,同时是另一个类的友元,但有时将函数作为两个类的友元更加合理。

    例如,假定有一个Probe类和一个Analyzer类,前者表示某种可编程的测量设备,后者表示某种可编程的分析设备。

    这两个类中都有内部时钟,且希望它们能够同步,则应包含下述代码行:

     1 class Analyzer   //forward declaration
     2 class Probe
     3 {
     4     friend void sync(Analyzer & a, const Probe & p);   // sync a to p
     5     friend void sync(Probe & p, const Analyzer & a);   // sync p to a
     6     ...
     7 }
     8 
     9 class Analyzer
    10 {
    11     friend void sync(Analyzer & a, const Probe & p);   // sync a to p
    12     friend void sync(Probe & p, const Analyzer & a);   // sync p to a
    13     ...
    14 }
    15 
    16 //define the friend functions
    17 inline void sync(Analyzer & a, const Probe & p)
    18 {
    19 ...
    20 }
    21 
    22 inline void sync(Probe & p, const Analyzer & a)
    23 {
    24 ...
    25 }

     前向声明使得编译器看到Probe类声明中的友元声明时,知道Analyzer是一种类型。

    关于友元的总结:

    理解友元的产生和意义,首先要从类说起;

    类对象的私有和保护数据成员只能通过类的公有方法访问。(这里暂时不讨论类的继承)

    这样做的好处是提高了数据的安全性和封装性,接口简洁。

    但是这种对数据的访问和修改的强限制手段,有时候会在某些场景下不方便。

    有些情况可能需要直接去访问或修改类的私有数据成员。那么为了提高类修改私有数据的灵活性,引入友元的概念。

    举个例子:假如你把一个人定义成朋友,那么这个朋友也获得了进出你家的资格,而不仅仅是你的家人。

    但是你的朋友不是你的家人,是有别于你的家人。所以友元不是类的成员

    友元可以是函数,类的成员函数,甚至类;

    其实还可以这样理解:把友元看成与类方法一样都是表达类接口的一种方式。

     

  • 相关阅读:
    android性能优化之布局优化
    android性能调优之traceview的使用
    android性能优化
    EditText光标居上
    ExecutorService的submit(Runnable x)和execute(Runnable x) 两个方法的本质区别
    android 静默安装
    android 内存优化
    image-webpack-loader在mac或ubuntu报错
    git重命名文件和文件夹
    js判断设备类型
  • 原文地址:https://www.cnblogs.com/grooovvve/p/10422039.html
Copyright © 2020-2023  润新知