zoukankan      html  css  js  c++  java
  • 【译】友元函数和友元类

    友元函数

    原则上,类的private和protected成员不能在其声明的类外进行访问。但是,这一规则对友元不起作用。

    友元是通过关键字friend声明的函数或类。

    如果声明一个外部函数为一个类的友元,这样就允许此函数操作这个类的private和protected成员。通过在类的内部声明这个外部函数,并在其前面加上friend关键字: 

    // friend functions
    #include <iostream>
    using namespace std;
    
    class CRectangle {
        int width, height;
      public:
        void set_values (int, int);
        int area () {return (width * height);}
        friend CRectangle duplicate (CRectangle);
    };
    
    void CRectangle::set_values (int a, int b) {
      width = a;
      height = b;
    }
    
    CRectangle duplicate (CRectangle rectparam)
    {
      CRectangle rectres;
      rectres.width = rectparam.width*2;
      rectres.height = rectparam.height*2;
      return (rectres);
    }
    
    int main () {
      CRectangle rect, rectb;
      rect.set_values (2,3);
      rectb = duplicate (rect);
      cout << rectb.area();
      return 0;
    }
    

    输出:24

    函数duplicate是类CRectangle的一个友元。在这个函数内部我们就可以操作CRectangle不同对象的private成员width和height。无论是在duplicate声明中,还是在之后main()中的使用。我们都没有认为duplicate是类CRectangle的一个成员。它不是!它只是可以操作类的private和protected成员,而不是其成员。

    友元函数可以作用于,例如,操作两个不同的类。通常来说,友元函数的运用已经超出了面向对象的编程方法,因此最好通过同一类的成员来操作此类。就像之前的例子,若将duplicate()整合到类CRectangle中,整个例子就会更加精简。

    友元类

    就像我们可以定义一个友元函数,我们也可以定义类的友元类。假设第一个类可以操作第二个类的protected和private成员。 

    // friend class
    #include <iostream>
    using namespace std;
    
    class CSquare;
    
    class CRectangle {
        int width, height;
      public:
        int area ()
          {return (width * height);}
        void convert (CSquare a);
    };
    
    class CSquare {
      private:
        int side;
      public:
        void set_side (int a)
          {side=a;}
        friend class CRectangle;
    };
    
    void CRectangle::convert (CSquare a) {
      width = a.side;
      height = a.side;
    }
      
    int main () {
      CSquare sqr;
      CRectangle rect;
      sqr.set_side(4);
      rect.convert(sqr);
      cout << rect.area();
      return 0;
    }
    

    输出:16

    在这个例子中,我们将CRectangle声明为CSquare的一个友元,因此CRectangle成员函数就可以操作CSquare的protected和private成员,具体就是描述正方形边长的CSquare::side。

    你也可以在这段程序的开头看到一些新东西:类CSquare的空声明。这是需要的,因为在类CRectangle的声明中我们涉及到类CSquare(作为convert()的参数)。类CSquare的定义在后面,如果我们不在之前包括其空声明,CSquare在CRectangle定义内部就是不可见的。

    友元不是相互的,如果我们不显示指定。在我们的例子中,CRectangle是类CSquare的一个友元,但是CRectangle并不认为CSquare是其友元。因此CRectangle可以操作CSquare的protected和private成员,但反之不然。当然,如果需要,我们可以将CSquare声明为CRectangle的一个友元。

    原文:http://www.cplusplus.com/doc/tutorial/inheritance/

  • 相关阅读:
    深入学习Motan系列(二)——服务发布
    深入学习Motan系列(一)——入门及知识zookeeper储备
    Guava Cache 总结
    Jetty学习(一)
    群发百万邮件
    Project ACRN documentation
    Storage Performance Development Kit
    DPDK Test Plans
    golang 判断前缀后缀、包含关系
    golang multiconfig 示例
  • 原文地址:https://www.cnblogs.com/dahai/p/2055123.html
Copyright © 2011-2022 走看看