原创 C++学习之路 (七) 类之间的关系

2014-2-15 09:32 947 12 12 分类: 软件与OS 文集: C++ 学习之路

类之间的关系(Relationships between classes)

 

1.友元函数(Friend functions)

     前面的章节中我们已经看到了对 class 的不同成员存在 3 个层次的内部保

护:publicprotected private。在成员为 protected private 的情况下,它们

不能够被从所在的 class 以外的部分引用。然而,这个规则可以通过在一个 class 中使

用关键字friend 来绕过,这样我们可以允许一个外部函数获得访问 class protected

private 成员的能力。

    为了实现允许一个外部函数访问 class private protected 成员,我们必须在

class 内部用关键字 friend 来声明该外部函数的原型,以指定允许该函数共享 class

成员。在下面的例子中我们声明了一个 friend 函数 duplicate

// friend functions

#include

class CRectangle

{

int width, height;

public:

void set_values (int, int);

int area (void) {return (width *height);}

friend CRectangle duplicate (CRectangle); //声明一个友元函数 duplicate 返回值和

输入参数为CRectangle类型

};

void CRectangle::set_values (int a, intb)

{

width = a;

height = b;

}

CRectangle duplicate (CRectangle rectparam) //该函数并没有将其范围限定为CRectangle

{

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();

}

函数 duplicate CRectangle friend,因此在该函数之内,我们可访问 CRectangle类型的各个 object 的成员 width height。注意duplicate()的声明中,及其在后面 main()里被调用的时候,我们并没有duplicate 当作 class CRectangle 的成员,它并不是。

friend 函数可以被用来实现两个不同 class 之间的操作。广义来说,

使friend 函数是面向对象编程之外的方法,因此,如果可能,应尽量使

class 的成员函数来完成这些操作。比如在以上的例子中,将函数

duplicate() 集成在 class CRectangle 可以使

程序更短。

友元类 (Friend classes)

就像我们可以定义一个 friend 函数,我们也可以定义一个 class 是另一个的 friend

以便允许第二个 class 访问第一个 class protected private 成员。

// friend class

 

#include

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; // CRectangleCSquare的友元类

};

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

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /2 下一条