第6章 类的友元和特殊成员
发布时间:2024-10-23
发布时间:2024-10-23
第6章 类的友元和特殊成员
第6章 类的友元和特殊成员6.1 友元的作用 6.2 友元函数 6.3 友元类 6.4 常类型 6.5 静态成员
第6章 类的友元和特殊成员
6.1 友元的作用
友元提供了不同类或对象的成员函数之间、类的成员函 数与一般函数之间进行数据共享的机制。也就是说,通 过友元的方式,一个普通函数或者类的成员函数可以访 问到封装于某一个类中的数据。这相当于给类的封装挖 了一个小孔,通过它,外界可以看到类内部的一些属性。
第6章 类的友元和特殊成员
先来看一段程序。 #include<iostream.h> class A { private: int x; public: void display( ){cout<<x<<endl;} int get( ){return x;} };
class B { private: A a; public: void set(int); void display( ); };
第6章 类的友元和特殊成员
这是类组合的情况,B类中内嵌了A类的对象,但 是B的成员函数却无法直接访问A的私有成员x。从数 据的安全角度来说,这无疑是最安全的,内嵌的部件 相当于一个黑盒。但是使用起来多少有些不便。例如, 按如下形式实现B的成员函数set( )会引起编译错误: void B::set(int k) {a.x=k;} 由于A的对象内嵌于B中,能否让B的函数直接访 问A的私有数据呢?这就需要寻求一种使得类以外的对 象或函数能够访问类中的私有成员的方法。C++为上 述这种需求提供了语法支持,这就是友元。
第6章 类的友元和特殊成员
6.2 友元函数 如果友元是普通函数或类的成员函数,则称为友元 函数。友元函数是在类声明中由关键字friend修饰的非成 员函数。 普通函数声明为友元函数的形式如下: friend <类型标识符> <友元函数名>(参数表) 成员函数声明为友元函数的形式如下: friend <类型标识符> <类名>::<友元函数名>(参数表)
第6章 类的友元和特殊成员
说明: ① 友元函数的声明可以在类声明中的任何位置, 既可在public区,也可在protected区,意义完全一样。 ② 友元函数的定义一般放在类的外部,最好与类 的其它成员函数定义放在一起。 友元函数不是本类的成员函数,但是它可以通过 对象名访问类的所有成员,包括私有和保护成员
第6章 类的友元和特殊成员
6.3 友元类如果友元是一个类,则称为友元类。友元类的声 明形式如下: friend class <友元类名> 说明: ① 友元类的声明同样可以在类声明中的任何位置。 ② 友元类的所有成员函数都成为友元函数。 例如,若A类为B类的友元类,则A类的所有成员 函数都是B类的友元函数,都可以访问B类的私有和保 护成员。
第6章 类的友元和特殊成员
通过友元类声明,友元类的成员函数可以通过对象 名直接访问到隐藏的数据,达到高效协调工作的目的。 在较为复杂的程序中,实现
不同类之间的数据共享,友 元类的使用是很必要的。现在将本节开头部分的程序段 修改成如下形式,以便实现B类的成员函数直接访问A类 私有成员x的目的。
第6章 类的友元和特殊成员 现在看看本节开始的问题怎么解 决: #include<iostream.h> class A { private: int x; public: void display( ){cout<<x<<endl;} int get( ) {return x;} friend class B; };
class B { private: A a; public: void set(int); void display( ); }; void B::set(int k){a.x=k;}
第6章 类的友元和特殊成员
关于友元,还有两点需要注意: ① 友元关系是不能传递的。B类是A类的友元,C 类是B类的友元,C类和A类之间如果没有声明,就没 有任何友元关系,不能进行数据共享。 ② 友无关系是单向的。如果声明B类是A类的友元, B类的成员函数就可以访问A类的私有和保护数据,但 A类的成员函数却不能访问B类的私有和保护数据。
第6章 类的友元和特殊成员
6.4 常类 型使用const关键字声明的对象称为常对象。常对象的 声明形式如下: const <类名> <对象名> 或 <类名> const <对象名> 声明常对象的同时,也要进行初始化,而且该对象 以后不能再被更新。现在来看下面的程序:
第6章 类的友元和特殊成员 class A { private: int x,y; public: A(int i=0,int j=0) {x=i;y=j;} //... };
const A cobj1;//将不能调用普通成员函数A const cobj2(3,4); //...
在上面的程序中,分别用两种形式声明了两个常对象 cobj1和cobj2,并在声明的同时对它们进行了初始化。
第6章 类的友元和特殊成员
改变对象的数据成员值有两个途径: 一是在类外通过对象名访问其公有数据成员,这时语法 会限制不能再赋值; 二是在类的成员函数中改变数据成员的值。然而几乎无 法预料和统计哪些成员函数会改变数据成员的值。因 此,语法只好规定不能通过常对象调用普通的成员函 数。 常对象是不是没有任 何可用的对外接口了?
第6章 类的友元和特殊成员#include<iostream.h> #include<math.h> class point { private: double x,y; public: point(double xx=0,double yy=0) {x=xx;y=yy;} double get_x( ) {return x;} double get_y( ) {return y;} }; int main() { const point p; p.get_x(); //出错 }
第6章 类的友元和特殊成员
常成员函数 使用const关键字声明的函数称为常成员函数。常 成员函数声明的形式如下: <类型标识符> <函数名>(参数表) const; 说明: ① const是加在函数声明后面的类型修饰符,它是 函数类型的一个组成部分,因此,在实现部分也要带 const关键字。
第6章 类的友元和特殊成员
② const关键字可以被用于对重载函数的区分。例 如,可以在类中这样声明: void fun( ); void fun( ) const; ③ 常成员函数不能更新对象的数据成员,也不能 调用该类中没有
用const修饰的成员函数。 ④ 如果将一个对象说明为常对象,则通过该对象 只能调用它的常成员函数,而不能调用其它成员函数。