VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > C#编程 >
  • C++教程之类之间的关系(Relationships between classes)

本站最新发布   Python从入门到精通|Python基础教程
试听地址  
https://www.xin3721.com/eschool/

类之间的关系(Relationships between classes)

Friend 函数 (friend 关键字)

在前面的章节中我们已经看到了对class的不同成员存在3个层次的内部保护:public, protected 和 private。在成员为 protected 和 private的情况下,它们不能够被从所在的class以外的部分引用。然而,这个规则可以通过在一个class中使用关键字friend来绕过,这样我们可以允许一个外部函数获得访问class的protected 和 private 成员的能力。
为了实现允许一个外部函数访问class的private 和 protected 成员,我们必须在class内部用关键字friend来声明该外部函数的原型,以指定允许该函数共享class的成员。在下面的例子中我们声明了一个 friend 函数 duplicate:
    // friend functions
    #include <iostream.h>
    
    class CRectangle {
        int width, height;
      public:
        void set_values (int, int);
        int area (void) {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();
    }                     
24
函数duplicate是CRectangle的friend,因此在该函数之内,我们可以访问CRectangle 类型的各个object的成员 width 和 height。注意,在 duplicate()的声明中,及其在后面main()里被调用的时候,我们并没有把duplicate 当作class CRectangle的成员,它不是。
friend 函数可以被用来实现两个不同class之间的操作。广义来说,使用friend 函数是面向对象编程之外的方法,因此,如果可能,应尽量使用class的成员函数来完成这些操作。比如在以上的例子中,将函数duplicate() 集成在class CRectangle 可以使程序更短。
 

Friend classes (friend)

就像我们可以定义一个friend 函数,我们也可以定义一个class是另一个的friend,以便允许第二个class访问第一个class的 protected 和 private 成员。
    // friend class
    #include <iostream.h>
    
    class CSquare;
 
    class CRectangle {
        int width, height;
      public:
        int area (void) {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 的friend,因此CRectangle可以访问CSquare 的protected 和 private 成员,更具体地说,可以访问CSquare::side,它定义了正方形的边长。
在上面程序的第一个语句里你可能也看到了一些新的东西,就是class CSquare空原型。这是必需的,因为在CRectangle 的声明中我们引用了CSquare (作为convert()的参数)。CSquare 的定义在CRectangle的后面,因此如果我们没有在这个class之前包含一个CSquare 的声明,它在CRectangle中就是不可见的。
这里要考虑到,如果没有特别指明,朋友关系(friendships)并不是相互的。在我们的CSquare 例子中,CRectangle 是一个friend类,但因为CRectangle 并没有对CSquare作相应的声明,因此CRectangle 可以访问CSquare 的 protected 和private 成员,但反过来并不行,除非我们将 CSquare 也定义为CRectangle的 friend。
相关教程