当前位置:首页 >> 计算机软件及应用 >>

C语言4友元


C++程序设计
第四章 友元

内容提要
? 为什么引入友元 ? 友元函数 ? 友元类

4.1 为什么引入友元
? 类具有封装和信息隐藏的特性。只有类的成员函数才能访 问类的私有成员,程序中的其它函数是无法访问私有成员 的。非成员函数可以访问类中的公有成员,但是如果将数 据成员都定义为公有的,又将破坏了隐藏的特性。另外, 在某些情况下,特别是在对某些成员函数多次调用时,由 于参数传递、 类型检查和安全性检查等需要开销,会影 响程序的执行效率。 ? 为了解决上述问题,提出了一种使用友元的方案。友元是 一种定义在类外的普通函数,但它需要在类体内进行说明, 为了与该类的成员函数相区别,在说明时前面加上关键字 friend。友元不是成员函数,但是它可以访问类中的私 有成员。友元提供了在不同类的成员函数之间、类的成员 函数与一般函数之间进行数据共享的机制。通过友元,一 个普通函数或另一个类中的成员函数可以访问类中的私有 成员和保护成员。友元的正确使用能提高程序的运行效率, 但破坏了类的封装性和数据的隐蔽性。所以使用时需慎重。 ? 友元可以是一个函数,该函数称为友元函数;友元也可以 是一个类,该类被称为友元类。

4.2 友元函数

1、定义格式
? 定义友元函数的方式是在类定义中用关键 词friend说明该函数,其格式如下: friend < 类型 > < 友元函数名 > ( < 参数表 >);

2、说明:
? 友元函数说明的位置可在类的任何部位,既可在 public 区,也可在 protected 区,意义完全一样。 友元函数定义则在类的外部,一般与类的成员函 数定义放在一起。 ? 类的友元函数可以直接访问该类的所有成员,但 它不是成员函数,可以像普通函数一样在任何地 方调用。友员函数的定义方法是在类的任何地方 象定义其他函数一样定义该函数,并在其前面加上 关键字friend即可。 友员函数虽然在类内定义, 但它不是这个类的成员函数,它可以是一个普通 函数,也可以是其他类的成员函数,在其函数体 中通过对象名访问这个类的私有或保护成员。

例4.1
#include "stdafx.h" #include "iostream.h" class Window { public: Window(int x,int y,int h,int w) { X=x,Y=y,H=h,W=w; } friend long Area(Window & WinObj); //在类中定义出友元函数的原型 int getH() { return H; } int getW() { return W; } private: int X,Y,H,W; }; long Area(Window & WinObj) //在类外定义出友元函数的函数体 { return (long)WinObj.H*WinObj.W; } void main() { Window winA(10,10,300,300); cout<<"Window Area is "<<Area(winA)<<endl; }

3、友元函数与成员函数在编成方面的 不同点
(1)友员函数在类体内应该采用friend加以限定, 但成员函数不需要; (2)友员函数在类体外不需要采用“类名::”加以 限定; (3)调用它时不需要采用“对象名.成员名”方式, 而是直接调用它; (4)由于友元函数不是成员函数,因而无this指 针,在函数体中访问对象中的成员时必须通过对 象名(可将形参定义为引用),而在成员函数体 内可以直接访问成员数据。

4、友元函数与一般函数(非成员函数) 在编程方面的不同点
(1)友员函数在类体内应该采用friend加 以限定,但非成员函数不需要再类中声明; (2)在友元函数体内可以利用对象访问类中 的private成员,但非成员函数则不能。

4.3 友元类
(1)定义格式
? C++允许说明一个类为另一个类的友元类(friend class)。 ? 如果A是 B的友员类,则 A中的所有成员函数可以 像友员函数一样访问 B 类中的所有成员。定义格 式如下: class B { friend class A; //A的所有成员函数均为B的友员函


//… }

(2)说明
? 友元关系不可以被继承。假设类 A 是类 B 的友元,而类 C 从类B派生,如果没有在类C中显式地使用下面的语句: friend class A; ? 那么,尽管类 A是类 B的友元,但这种关系不会被继承到 类C,也就是说,类C和类A没有友元关系,类A的成员函 数不可以直接访问类C的受保护成员和私有成员。 ? 不存在“友元的友元”这种关系。假设类A是类B的友元, 而类B是类C的友元,即是说类B的成员函数可以访问类C 的受保护成员和私有成员,而类A的成员函数可以访问类 B的受保护成员和私有成员;但是,类A的成员函数不可 以直接访问类C的受保护成员和私有成员,即是说友元关 系不存在传递性。

例4.2 p100例
? 本例实现的是堆栈的压入和弹出。有两个 类,一个是结点类,它包含结点值和指向 上一结点的指针;另一个类是堆栈类,数 据成员为堆栈的头指针,它是结点类的友 元。 ? 程序


赞助商链接
相关文章:
更多相关标签: