C++入门学习文档
第三章 类(class)及其对象(object)的封装(encapsulation) ——数据及其操作的统一管理
上面第二章§2.6.5“函数指针与其指针数组”的举例程序err_&_action_1.cpp中,要求void (*action[ ] ) ( )函数指针数组和字符指针数组char *err_msg[ ]的各单元顺序必须完全对应,也即,必须将两个数组中有关冷却水、通风或润滑油的各单元全都一一对应才有意义。删除单元时,必须成对删除;插入新单元时,也必须成对插入。而且顺序不准弄错。C语言无法完全解决这个问题;而C++提供了封装技术,可以完全解决这个问题。
以冷却水和通风为例,可将各个相关的单元分别封装在各个类(class)内。如以下两个类: class water {
double flow; //数据:水流量 char *err_msg_water ; //数据:断水警告 void act_water( ); //函数:采取动作,开启水阀 };
class vent //通风 {
double flow; //数据:通风流量 char *err_msg_vent; //数据:无风警告 void act_vent( ); //函数:采取动作,开启风扇 };
随后可将字符指针char *err_msg_water和char *err_msg_vent分别初始化为指向警告字符串。
再看另一个例子。第二章§2.7“引用”中提到,主函数内具有引用的变量必须不是某个函数内部的局部变量,不然当退出该函数时,将出现“悬挂引用”的现象。第二章的例子中全部使用全局变量。但根据软件工程的观点,应尽少使用全局变量。为解决此问题,可依靠“封装”,使用封装后的静态变量,它的生命周期很长,不致出现“悬挂引用”现象。如下: class ref_example {
static double temp; //数据:水温 double &ref; //数据:水温变量temp的引用 }
随后ref可初始化为temp的引用。
该类的对象可被定义为具有全局性,因此这个对象的各个成员也都具有全局性,该数
C++入门学习文档
据的引用不会遭遇“悬挂引用”的命运。但数据temp又不完全是全局变量,它只是被封装的全局变量。不是所有函数都能访问它,只有具有访问权的函数才能访问它,从而在一定程度上避免了使用全局变量时可能遇到的被随意修改的危险。 引用的初始化将在第三章§3.5.1.1“特定类型数据成员的初始化”中介绍。
以下程序依靠封装,能够保证需要修改数据时才能修改,不准修改数据时就不能修改。
[例1]使用封装以便保护数据 // encapsul.cpp
// The case of using capsulation to protect datum 'i'(不是data) #include <iostream.h> class integ //用户建立一个类,以便封装 {
int j; //被保护的数据 public:
integ( ) { j = 6; } //构造函数 int sq() { return j*j; } //求平方的函数 int read() { return j; } //读数据的函数 };
void main() {
integ obj; //建立对象并初始化 cout << obj.read() << endl; //读数据 cout << obj.sq( ) << endl; //读平方值 }
/* Results: 6
36 */
从以上程序看出,不允许外部函数(如主函数main( ))等直接访问(读取或修改)class integ中的数据成员j,而必须通过调用类class integ的成员函数read( ),才能读取j。如需求其平方值,则须调用成员函数sq( ),但这些函数仍然无法改变数据j。
封装是指将对象的属性(attribute)(或称数据内容)和作用于这些属性上的操作“类”。
封装具有以下特点:
1. 定义)。
2. 从而访问私有数据。
C++入门学习文档
在第一章§1.2.1“编程语言特征”中曾提到:客观世界的各事物可按其共性分为各个类(称为基类),这些类是具有相同共性的各事物的集合,是这些事物的统一抽象。
C++按此设想定义了第二种数据类型,即用户自定义的数据类型,主要是“类”。
第二章已经介绍过第一种数据类型 --- 基本数据类型(即预定义类型)。本章将介绍第二种数据类型:类及其对象。
C++中,类是面向对象语言中相对独立的程序单位(程序块),对象是类的实例(instance),它具有自己的属性,可以执行一定操作(函数)。一个类具有两个成员部分:第一部分称为属性(Attributes)或数据成员(data members);第二部分称为实现(Implementation)或成员函数(member functions)。其数据成员可以是各种预定义类型和用户自定义类型的数据。本章§3.1“封装性”的[例1]中已介绍过一个类class integ。可以看出,它的首部是关键词class加上类名,类的全部内容(称为类体(class body),包括数据和函数)都包含于花括号内,最后以分号结束。
由于用户能够在需要时生成新的类(详见第四章),因此C++是可扩展语言(extensible language)。
成员函数可在类体之内、也可在类体之外被定义。规范的做法是将成员函数的说明部分(函数原型)放在类体之内,而将成员函数的定义部分放在类体之外。如下例: class integ //用户建立的一个类 {
int j; public:
integ( ) { j = 6; } //构造函数的定义部分 int sq( ); //成员函数的说明部分 };
int integ::sq( ) //成员函数的定义部分 { return j*j; }
实践中,当成员函数比较短小而且没有技术秘密时,就将成员函数的定义部分也放在类定义内。如下例: class integ //用户建立的一个类 {
int j; public:
integ( ) { j = 6; } //构造函数的定义部分 int sq( ) { return j*j; …… 此处隐藏:12623字,全部文档内容请下载后查看。喜欢就下载吧 ……