类之间的关系(Relationships between classes)
1.友元函数(Friend functions)
前面的章节中我们已经看到了对 class 的不同成员存在 3 个层次的内部保
护:public,protected 和 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; // CRectangle是CSquare的友元类
};
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条评论)
登录后参与讨论