C++语言程序设计项目实践(清华大学计算机基础教育课程系列教材)

C++语言程序设计项目实践(清华大学计算机基础教育课程系列教材)
作者: 编者:黄匀//何文河//郑莉
出版社: 清华大学
原售价: 35.00
折扣价: 28.00
折扣购买: C++语言程序设计项目实践(清华大学计算机基础教育课程系列教材)
ISBN: 9787302499459

作者简介

内容简介

第5章数据结构设计与实现 数据结构设计与实现 本章主要描述ContactList系统的总体数据结构设计与实现方法。数据结构设计应当遵循《需求说明书》和《概要设计说明书》的要求。由于ContactList系统使用了面向对象的思想,所以数据结构设计应当遵循面向对象的三大特性(抽象、封装和继承)。综上所述,本系统的数据结构的主要设计方法是定义相关类,在类中定义所需的数据成员和函数成员(部分自定义数据类继承了MFC系统提供的数据类)。 5.1CPerson类的设计与实现   在ContactList项目中,CPerson类主要描述一个联系人的信息,包括姓名、性别、手机号、QQ号和组编号,对每个属性属性都提供了Get/Set函数、基础数据存储以及其他函数的操作功能。ContactList项目的总体结构设计如图51所示。 图51总体结构设计图 5.2添加CPerson类 (1) 单击左下角的Class View切换到类视图,如图52所示。 图52类视图 (2) 在类视图中的ContactList上右击右击,在弹出的快捷菜单中选择Add→Class命令,如图53所示。 图53选择Class命令 (3) 弹出类向导对话框,选择C++ Class后单击Add按钮,如图54所示。 图54添加类 (4) 在类向导对话框中输入相应内容,如图55所示。 图55添加类命名  Class name: 表示添加类的名称。  .h file: 表示该类添加后生成的头文件,主要存放成员数据的声明。  .cpp file: 表示该类添加后生成的源文件源文件,主要存放成员数据的定义。 (5) 单击Finish按钮。 5.3添加CPerson类的成员变量 (1) CPerson类的成员变量设置如表51所示。 (2) 单击Class View切换到类视图。 (3) 双击双击CPerson类打开该类的Person.h头文件。表51CPerson类的成员变量 成员描述m_strName姓名: 描述一个名字,20个字符以内m_bMale性别: TRUE表示男;FALSE表示女m_strPhoneNo手机号: 11位数字m_strQQNoQQ号: 10位以内的数字m_iGroupNo组号: 全局字符串数组g_lstGroups的索引(4) 在Person.h文件中添加如下成员变量代码,然后保存,如图56所示。protected: CStringm_strName;//姓名: 20个字符以内 BOOL m_bMale; //性别: TRUE表示男;FALSE表示女 CString m_strPhoneNo; //手机号: 11位数字 CString m_strQQNo; //QQ号: 10位以内的数字 int m_iGroupNo; //组号: 全局字符串数组g_lstGroups的索引 图56CPerson成员变量 5.4添加CPerson类的成员函数 CPerson类的成员函数设置如表52所示。表52CPerson类的成员函数 续表成员 描述CPerson~CPerson默认构造构造函数和虚析构析构函数,这是由App Wizard自动创建的初始函数体。重载重载的构造函数用于成员变量初始化GetName/SetName获取/设置名字IsMale/SetMale判断/设置性别GetPhoneNo/SetPhoneNo获取/设置手机号码GetQQNo/SetQQNo获取/设置QQ号码GetGroupNo/SetGroupNo获取/设置分组类型打开Person.h文件,添加如下自定义内联成员函数代码,然后保存,如图57所示。public: CStringGetName(){ return m_strName; } BOOL IsMale() { return m_bMale; } CString GetPhoneNo() { return m_strPhoneNo; } CString GetQQNo() { return m_strQQNo; } int GetGroupNo() { return m_iGroupNo; } void SetName(CString strName) { m_strName=strName; } void SetMale(BOOL bMale) { m_bMale=bMale; } void SetPhoneNo(CString strPhoneNo) { m_strPhoneNo=strPhoneNo; } void SetQQNo(CString strQQNo) { m_strQQNo=strQQNo; } void SetGroupNo(int iGroupNo) { m_iGroupNo=iGroupNo; } 图57CPerson成员函数 5.5重载CPerson类的构造函数   重载是函数多用性的一个表现,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是用同一个函数实现功能类似但所处理数据类型不同的问题。本节重载CPerson类构造函数,使CPerson对象带默认参数值,即为后添加联系人功能的默认值。 (1) 在Person.h文件的CPerson类中添加下面的代码,如图58所示。CPerson(CString strName, BOOL bMale=TRUE, CString strPhoneNo=_T(\"88888888888\"), CString strQQNo=_T(\"0000\"), int iGroupNo=0); 图58重载CPerson类的构造函数声明 (2) 单击Solution Explorer切换到解决方案视图。 (3) 双击Person.cpp打开该文件,在相应的位置添加如下代码,如图59所示。CPerson::CPerson(CString strName, BOOL bMale, CString strPhoneNo, CString strQQNo, int iGroupNo) : m_strName(strName), m_bMale(bMale), m_strPhoneNo(strPhoneNo), m_strQQNo(strQQNo), m_iGroupNo(iGroupNo) { }//end of CPerson::CPerson() 图59重载CPerson类的构造函数定义 5.6CPerson成员变量的初始化 打开Person.cpp文件,在默认构造函数CPerson::CPerson(void)中添加如下代码,如图510所示。 m_strName=_T(\"Unknown\"); m_bMale=TRUE; m_strPhoneNo=_T(\"88888888888\"); m_strQQNo=_T(\"00000\"); 图510初始化CPerson成员变量 5.7CPersonList类的设计与实现 CPersonList记录整个通讯录对象,是元素类型为CPerson的动态数组,需要先用类型定义关键字 typedef 定义一个元素为CPerson的CArray类CPersons,再将CPersonList定义成CPersons的派生类(从而也是CArray的派生类),如图511所示。 图511CPerson的动态数组 5.8类模板和动态数组CArray 数组是在编码过程中经常用到的集合命名,它把具有相同类型的若干元素按无序的形式组织起来。普通数组使用起来很麻烦,在程序变化的过程中数组一般不是固定的,而是动态变化的,就像通讯录项目中联系人的数量一样,不同的使用者联系人的数量是不一样的,并且随着时间的发展联系人的数量也会有所改变,所以本项目为了解决联系人存储的问题,引入MFC中几个常用的类模板,其中用得最多的是CArray。 CArray是MFC中非常重要的类模板之一,使用类模板可以使用户为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型。类模板是对一批仅成员数据类型不同的类的抽象,程序员只要为这批类组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,从而大大提高编程效率。定义类模板的一般形式如下。 template <类型名 参数名1,类型名参数名2,…>  class 类名  {  类声明体  }; 本项目将通过CArray动态数组管理联系人的增/删/查/改,以提高对联系人的管理效率。CArray的原型声明如下。   templateclass CArray : public CObject (1) TYPE: 模板参数,指定存储在数组中对象的类型。TYPE是CArray返回的参数类型。 (2) ARG_TYPE: 模板参数,指定用来访问存储在数组中对象的变量类型,通常是TYPE的引用。ARG_TYPE是传递给CArray的参数类型。 CArray类在需要的时候可以动态收缩和扩展。数组索引总是从0开始。用户可以决定是固定数组上界还是允许当添加元素超过当前边界时扩展数组。内存被连续地分配到上界,即使一些元素可能为空。CArray在索引元素访问时是不变的,与数组大小无关。 在使用CArray之前用SetSize建立它的大小并为它分配内存。如果不使用SetSize,则为数组添加元素会引起频繁的重新分配和复制,频繁的重新分配和复制不仅没有效率,而且会导致产生内存碎片。 5.9添加CPersonList类   在项目中添加CPersonList类,添加的内容如图512所示。 图512添加CPersonList类 5.10CPersonList继承CArray功能   CArray是有动态数组功能的模板类,通过继承这一特性,CPersonList把CArray的动态数组功能特性继承给CPersonList,所以用户可以直接通过CPersonList继承过来的函数管理通讯录中的联系人。 (1) 打开PersonList.h文件,在文件的上面添加以下两个头文件,如图513所示。#include \"afxtempl.h\"//CArray要求的头文件 #include \"Person.h\" 图513添加头文件 (2) 在PersonList.h文件中添加定义CPersons的代码(代码如下),如图514所示。//定义一个元素为CPerson的CArray类CPersons typedef CArrayCPersons; 图514定义CPersons 以“个人通讯录”项目开发过程为主线,按照CMMI 2级简化模型逐步展开,以完成此项目的开发