您的当前位置:首页正文

C++面向对象程序设计实验指导书[1]

2023-11-24 来源:意榕旅游网


C++面向对象程序设计实验指导书

(v1.0)

刘恒洋 谭智编

重庆工学院计算机学院

2007年9月

C++面向对象程序设计实验指导书 目录

目录

绪论 .................................................................................................................................................. 1

0.1 写本书的目的 .................................................................................................................... 1 0.2 本书的结构安排 ................................................................................................................ 1 0.3 如何使用本书 .................................................................................................................... 2 实验一 C++基础 ............................................................................................................................. 3

1.1 实验目的 ............................................................................................................................ 3 1.2 实验内容 ............................................................................................................................ 3

1.2.1 程序阅读 ................................................................................................................. 3 1.2.2 程序设计 ................................................................................................................. 6 1.3 思考题 ................................................................................................................................ 7 实验二 类和对象—类的构建 ......................................................................................................... 8

2.1 实验目的 ............................................................................................................................ 8 2.2 实验内容 ............................................................................................................................ 8

2.2.1程序阅读 .................................................................................................................. 8 2.2.2 程序设计 ............................................................................................................... 10 2.3思考题 ............................................................................................................................... 10 实验三 类和对象—构造函数与析构函数 ................................................................................... 11

3.1 实验目的 .......................................................................................................................... 11 3.2 实验内容 .......................................................................................................................... 11

3.2.1程序阅读 ................................................................................................................ 11 3.2.2 程序设计 ............................................................................................................... 12 3.3思考题 ............................................................................................................................... 13 实验四 类和对象—对象传递与静态成员 ................................................................................... 14

4.1 实验目的 .......................................................................................................................... 14 4.2 实验内容 .......................................................................................................................... 14

4.2.1程序阅读 ................................................................................................................ 14 4.2.2 程序设计 ............................................................................................................... 17

实验五 派生与继承—单重派生 ................................................................................................... 18

5.1 实验目的 .......................................................................................................................... 18 5.2 实验内容 .......................................................................................................................... 18

5.2.1程序阅读 ................................................................................................................ 18 5.2.2 程序设计 ............................................................................................................... 20

实验六 派生与继承—多重派生 ................................................................................................... 21

6.1 实验目的 .......................................................................................................................... 21 6.2 实验内容 .......................................................................................................................... 21

6.2.1程序阅读 ................................................................................................................ 21 6.2.2 程序设计 ............................................................................................................... 24 6.3思考题 ............................................................................................................................... 24 实验七 多态性—函数与运算符重载 ........................................................................................... 25

7.1 实验目的 .......................................................................................................................... 25 7.2 实验内容 .......................................................................................................................... 25

7.2.1程序阅读 ................................................................................................................ 25

I

C++面向对象程序设计实验指导书 目录

7.2.2 程序设计 ............................................................................................................... 27 7.3思考题 ............................................................................................................................... 28 实验八 多态性—类型转换与虚函数 ........................................................................................... 29

8.1 实验目的 .......................................................................................................................... 29 8.2 实验内容 .......................................................................................................................... 29

8.2.1程序阅读 ................................................................................................................ 29 8.2.2 程序设计 ............................................................................................................... 31 8.3思考题 ............................................................................................................................... 31 实验九 模板类的构造 ................................................................................................................... 32

9.1 实验目的 .......................................................................................................................... 32 9.2 实验内容 .......................................................................................................................... 32

9.2.1程序阅读 ................................................................................................................ 32 9.2.2 程序设计 ............................................................................................................... 34 9.3思考题 ............................................................................................................................... 34 实验十 C++的I/O流类库 ............................................................................................................ 35

10.1 实验目的 ........................................................................................................................ 35 10.2 实验内容 ........................................................................................................................ 35

10.2.1程序阅读 .............................................................................................................. 35 10.2.2 程序设计 ............................................................................................................. 36 10.3思考题 ............................................................................................................................. 36 实验十一 C++程序、Windows程序和MFC程序 ..................................................................... 38

11.1 实验目的 ........................................................................................................................ 38 11.2 实验内容 ........................................................................................................................ 38

11.2.1 实验描述 ............................................................................................................. 38 11.2.2 实验步骤 ............................................................................................................. 39 11.2.3 实验结果分析 ..................................................................................................... 45 11.3思考题 ............................................................................................................................. 47 实验十二 简单单文档MFC程序设计 .................................................................................. 48

12.1 实验目的 ........................................................................................................................ 48 12.2 实验内容 ........................................................................................................................ 48

12.2.1 实验描述 ............................................................................................................. 48 12.2.2 实验步骤 ............................................................................................................. 49 12.2.3 实验结果 ............................................................................................................. 54 12.3思考题 ............................................................................................................................. 55 实验十三 简单对话框程序设计 ............................................................................................. 56

13.1 实验目的 ........................................................................................................................ 56 13.2 实验内容 ........................................................................................................................ 56

13.2.1 实验描述 ............................................................................................................. 56 13.2.2 实验步骤 ............................................................................................................. 56 13.2.3 实验结果 ............................................................................................................. 63 13.3思考题 ............................................................................................................................. 63 实验十四 简单数据库程序设计 ............................................................................................. 65

14.1 实验目的 ........................................................................................................................ 65 14.2 实验内容 ........................................................................................................................ 65

II

C++面向对象程序设计实验指导书 目录

14.2.1 实验描述 ............................................................................................................. 65 14.2.2 实验步骤 ............................................................................................................. 66 14.2.3 实验结果 ............................................................................................................. 73 14.3思考题 ............................................................................................................................. 74 综合练习 ........................................................................................................................................ 75 总结 ................................................................................................................................................ 76 参考书目 ........................................................................................................................................ 77

III

C++面向对象程序设计实验指导书 绪论

绪论

0.1 写本书的目的

面向对象程序设计语言是现今最流行的编程语言之一,C++语言是作为最早最流行的面向对象编程语言之一而发展起来的。学好C++语言不仅可以从面向过程的程序设计思想过渡到面向对象的程序设计思想,而且可以为以后学习其它的面向对象语言打下坚实的基础,使得学习其它的面向对象编程语言变得轻松、容易。 实验作为学习C++语言不可缺少的一个环节不仅可以加深学生对C++面向对象思想的理解,同时可以提高学生的动手编程能力,培养学生良好的编码习惯。目前关于C++语言的理论教材比较多,但是适合学生练习的实验指导书却比较少,这严重影响了学生对C++这门课程的学习。大多数情况下,学生学习C++语言之前都刚刚学习过C语言程序设计这门课程,从编程环境到编程语言同时转换过来需要一定的时间和合理的指引,同时在学习C++理论知识的过程中,学生很少也很难把C++程序设计和现在社会上比较流行的基于VC6.0的MFC程序设计联系起来,所以很难让学生在学习C++语言的同时,提升学生基于VC6.0的MFC程序设计的能力。编写本书的目的就是从以上几点来考虑的,首先要把学生从以前的编程环境中脱离出来,然后循序渐进地介绍新的编程环境的新知识点,同时把C++的语法结构融入到基于VC6.0的MFC程序设计中去,从而实现学生轻松掌握C++这门程序设计语言和习惯编程环境以及理解C++语法和MFC之间的关系的目的,从而提高学生的程序设计能力和学生程序设计的成就感。

0.2 本书的结构安排

实验课程的安排离不开理论课程的学习,本书的编排以知识点为核心,理论教材蓝本为《C++面向对象程序设计教程》(第2版)陈维兴 林小茶编著,清华大学出版社出版。通过为不同的知识点设计相应的实验程序,来达到学生练习和理解C++语言面向对象的思想的目的,同时本书还设计了一些程序设计课后练习题,设计本部分有三个目的:一个是有些课堂练习中没有办法练习到的知识点将在这部分体现,指导老师可以根据需要来增删课堂的讲解内容;另一个是为一部分有能力有兴趣深入学习C++程序设计的同学提供一些练习题,从而提升这部分学生的程序设计能力;第三就是避免有些学生在做实验的过程中盲目按照指导书中的步骤一步一步地不加思考地写程序,学生要回答这些问题,就必须看懂这些程序中隐含的知识点,从而达到理论知识和实践知识更好地结合。 对于课堂练习,本书共安排了十个实验,共32个学时,实验安排如下: 实验一 C++基础 (2学时) 实验二 类和对象—类的构建 (2学时) 实验三 类和对象—构造函数与析构函数 (2学时) 实验四 类和对象—对象传递与静态成员 (2学时) 实验五 派生与继承—单重派生 (2学时) 实验六 派生与继承—多重派生 (2学时) 实验七 多态性—函数与运算符重载 (2学时)

1

C++面向对象程序设计实验指导书 绪论

实验八 多态性—类型转换与虚函数 (2学时) 实验九 模板类的构造 (2学时) 实验十 C++的I/O流类库 (2学时) 实验十一 C++程序、Windows程序和MFC程序 (3学时) 实验十二 简单单文档MFC程序设计 (3学时) 实验十三 简单对话框程序设计 (3学时) 实验十四 简单数据库程序设计 (3学时) 另外本书还安排了第三部分—综合练习,作为学生提高部分,学生通过第三部分的练习不仅可以巩固前面学到的基本知识,还可以扩充相关方面的程序设计知识,更为重要的是可以让学生自主地设计一个完整的系统,从而达到提高学生综合程序设计能力的目的。

0.3 如何使用本书

面向对象程序设计语言出现的目的就是为了设计大型的软件系统,但是教学过程中很难让学生在课堂上实现一个大型的(甚至是成型)的系统,所以作为教师应该引导学生在实现一个简单的功能性的程序的同时让学生思考,思考如何把这个地方的技术实现到一个复杂的应用系统中去;另外教师要充分利用本书中第二部分的练习,引导学生去思考如何利用C++的相关技术从头到尾设计一个具有实用价值的应用程序。

作为学生如果只是简单地按照本书中提供的步骤一步一步完成某一个程序,而不去思考为什么要这样做的话,那么学生能学到的知识也仅仅是C++的语法而已,并不能真正理解C++面向对象的思想,最终不能设计出好的程序来。所以学生不仅要全部实现本书中的课堂练习,得出正确的结果,而且在完成了程序后还要思考本程序为什么要这样设计,如果换成其它的程序设计语言会怎么实现,只有这样才能够真正理解C++的精髓,从而掌握C++。

另外学生在学习最后四个实验的时候一定不要忘记前面C++语法知识,能否合理地将C++的三大特性运用到MFC的程序设计中是提高程序运行效率,存储效率和程序封装性一个最有效的手段。

学生在设计本实验指导书第三部分程序的时候,需要自己查阅相关方面的技术资料才能完成相关功能,因为安排这部分的目的就是为了提升学生自主学习的能力和综合程序设计能力,因此这部分的内容并没有安排相关理论知识的讲解。另外教师也可以把这部分的内容用于学生课程设计的程序设计题目。

注:本书中所有的程序都采用VC++6.0(英文版)编程环境,并且全部在该环境下编译运行通过!

2

C++面向对象程序设计实验指导书 实验一

实验一 C++基础

1.1 实验目的

1.进一步了解和熟悉VC++6.0开发环境,学会在VC++6.0环境下调试程序; 2.熟悉C++中简单的标准输入输出函数的实用;

3.理解const修饰符的作用,并学会应用const修饰符; 4.理解内置(内联)函数的优缺点并学会使用内置函数; 5.理解和使用函数重载以及带默认参数的函数; 6.使用new和delete进行动态内存管理; 7.理解和使用引用。

1.2 实验内容 1.2.1 程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

int max_def(int x, int y) {

return (x>y?x:y); }

int max_def(int x, int y, int z) {

int temp = 0;

return (temp=(x>y?x:y))>z?temp:z; }

double max_def(double x, double y) {

return (x>y?x:y); }

int main() {

int x1 = 0; int x2 = 0;

double d1 = 0.0; double d2 = 0.0; x1 = max_def(5,6);

3

C++面向对象程序设计实验指导书 实验一

}

x2 = max_def(2,3,4); d1 = max_def(2.1,5.6);

d2 = max_def(12.3,3.4,7.8);-----------------------------------------------------① cout<<\"x1=\"<cout<<\"d2=\"<问题一:上述程序的输出结果是什么?

问题二:哪些情况可以参与函数的重载?

函数参数的类型不同,或者参数的个数不同,或者二者兼而有之。 问题三:①处调用的是哪个函数?

调用的是def(int x, int y, int z)这个函数。

问题四:②处的输出结果为什么是d2=12,而不是d2=12.3?

因为调用的是def(int x, int y, int z)这个函数,所以输出值为整型。

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

int main() {

int *p1 = new int; -----------------------------------------------------① int *p2 = new int(0); -----------------------------------------------------② char *p3 = new char[64]; -----------------------------------------------------③ delete []p3; return 1;

4

C++面向对象程序设计实验指导书 实验一

}

问题一:①、②、③处动态申请内存分别代表什么不一样的意思?

1处代表new动态分配存放一个整数的内存空间,并将其首地址赋给指针变量p1. 2处代表new动态分配内空间,并将0作为初始值赋给首地址p2。

3处代表new动态分配存放数组的内存空间,并将首地址赋给指针变量p3. 问题二:该程序存在什么隐患?改正该程序使隐患消除。 没有释放动态分配的数组存储空间,同意导致没有足够的内存满足分配要求,导致动态分配空间失败。

3.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

void swap(int a, int b) {

int temp = a; a = b; b = temp; }

void swap(int *a, int *b) {

int temp = *a; *a = *b; *b = temp; }

int main() {

int i = 5; int j = 10;

cout<<\"Before swap: i=\"<swap(i,j); -----------------------------------------------------① cout<<\"After the first swap: i=\"<swap(&i,&j); -----------------------------------------------------② cout<<\"After the second swap: i=\"<return 1; }

问题一:上述程序的输出结果是什么?

5

C++面向对象程序设计实验指导书 实验一

问题二:①处函数调用后并不能实现两个数的交换,而②处却可以,为什么?

因为1处调用的函数是void swap(int a, int b),i、j将值传给a、b后,a、b值的交换与i、

j无关所以不能实现两个数的交换。2处调用的函数是void swap(int *a, int *b),将i、j地址传给*a、*b,*a、*b交换数值即交换i、j地址,所以i、j值交换了。

问题三:②处调用的是哪个重载函数?

调用void swap(int *a, int *b) 这个函数。

1.2.2 程序设计

1.使用函数重载的方法定义两个重名函数,分别求出整形数平面间两点间距离和双精度平面间两点间距离,如果没有输入第二点的坐标则默认为圆点(0,0)。 #include

int fun_c(int i0,int j0,int i1,int j1) {return (i0-i1)*(i0-i1)+(j0-j1)*(j0-j1); }

double fun_c(double x0,double y0,double x1,double y1) {return (x0-x1)*(x0-x1)+(y0-y1)*(y0-y1); }

int main()

{int i0=1,i1=2,j0=3,j1=4;//(i0,j0) (i1,j1)分别为两个点

double x0=1.1,x1=2.2,y0=3.3,y1=4.4;//(x0,y0) (x1,y1)分别为两个点 cout<<\"距离为\"<2.设计一个函数:exchange(float x, float y, float z),当调用exchange(a,b,c)时,将a的内容

6

C++面向对象程序设计实验指导书 实验一

赋值给b,b的内容赋值给c,c的内容赋值给a,要求采用引用的方式来实现。 #include

void exchange(float &x, float &y, float &z) { float temp = x; x=z; z=y; y = temp; }

int main() { float a= 5; float b = 10; float c=15; cout<<\"Before exchange: a=\"<1.3 思考题

1.自己设计一个程序,测试const的三种用法:指向常量的指针,常指针,指向常量的常指针。

2.编写一个函数,实现两个字符串变量的交换,要求参数用引用。

7

C++面向对象程序设计实验指导书 实验二

实验二 类和对象—类的构建

2.1 实验目的

1.类的定义; 2.类对象的使用;

3.类成员变量的定义和使用; 4.类成员函数的定义和使用; 5.理解类的作用域; 6.理解类的声明;

7.理解类中private和public权限的声明依据。

2.2 实验内容 2.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

class CDate {

void Set(int m, int d, int y ) { month = m ; day = d ; year = y ; }

int IsLeapYear() { return (year%4 == 0 && year%100 != 0)||(year%400 == 0); } public:

void Print() { cout<int month; int day; int year; };

8

C++面向对象程序设计实验指导书 实验二

void main() {

CDate a; -----------------------------------------------------① a.Set(10,15,2007) ; a.Print(); }

问题一:以上程序编译能通过吗,为什么,应该如何改正?

问题二:类CDate中分别有哪些成员函数和成员变量,它们分别属于哪种访问权限? 问题三:①处语句的意思是什么?

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

int month;//全局变量 int day; int year;

void Set(int m,int d,int y) -----------------------------------------------------a {

::month=m; -----------------------------------------------------① ::day=d; ::year=y; }

class CDate {

public:

void Set(int m,int d,int y) -----------------------------------------------------b { ::Set(m,d,y); -----------------------------------------------------② }

void Print() { cout<int month; //成员变量 int day; int year; };

void main() {

CDate a;

a.Set(10,15,2007) ; a.Print();

9

C++面向对象程序设计实验指导书 实验二

}

问题一:①处是在给成员变量赋值,还是在给全局变量赋值,如果去掉域作用符::,程序是否还能正确运行?

问题二:②处调用的哪个函数,如果去掉域作用符::,程序是否还能正确运行? 问题三:该程序的输出结果是什么,试解释该输出结果。

2.2.2 程序设计

1.试设计一个复数类,该类有实部和虚部两个成员数据,成员数据采用私有访问权限,同时该类有两个共有成员函数,分别用来设置成员数据和输出成员数据,在主函数中分别采用对象方式,指针方式和引用方式来调用该类的公有函数设置和输出成员数据。

2.3思考题

1.试指出以下程序的错误,并改正之。

#include

class CPoint {

public:

unsigned x, unsigned y;

bool IsInCircle(CCircle *Circle) { return (((x-Circle->Center.x)*(x-Circle->Center.x)

+(y-Circle->Center.y)*(y-Circle->Center.y))<=Circle->Radius*Circle->Radius); } };

class CCircle {

public:

unsigned Radius; CPoint Center; };

void main() { }

10

C++面向对象程序设计实验指导书 实验三

实验三 类和对象—构造函数与析构函数

3.1 实验目的

1.理解掌握this指针的作用和用法; 2.理解掌握构造函数的定义和作用; 3.掌握构造函数的使用;

4.理解掌握拷贝构造函数的定义和使用; 5.理解掌握构造函数的重载;

6.理解掌握析构函数的定义和使用。

3.2 实验内容 3.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

class CPoint {

public:

void Set(int x,int y); void Print(); private: int x; int y; };

void CPoint::Set(int x,int y) {

x = x; y = y; }

void CPoint::Print() {

cout<<\"x=\"<void main()

11

C++面向对象程序设计实验指导书 实验三

{ }

CPoint pt; pt.Set(10,20); pt.Print();

问题一:以上程序编译能通过吗,试解释该程序?

问题二:以上程序的运行结构是否正确,如果不正确,试分析为什么,应该如何改正? 2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include

class CPerson {

public:

void Print(); private:

CPerson(); private: int age; char *name; };

CPerson::CPerson() { }

void CPerson::Print() {

cout<<\"name=\"<void main() {

CPerson ps(23,\"张三\"); ps.Print(); }

问题一:以上程序存在三处大错误,在不改变主函数内容的前提下,试改正该程序。

3.2.2 程序设计

1.设计实现一个CPoint类,满足以下要求: a. 该类包含两个整型成员变量x(横坐标)和y(纵坐标),以及一个输出函数Print()用来输出横坐标和纵坐标,要求不可以在类的外部直接访问成员变量; b.可以采用没有参数的构造函数初始化对象,此时的成员变量采用默认值0; c.可以采用直接输入参数的方式来初始化该类的成员变量;

12

C++面向对象程序设计实验指导书 实验三

d.可以采用其它的CPoint对象来初始化该类的成员变量; e.设计一个主函数来测试以上功能。

3.3思考题

1.设计一个CStudent(学生)类,并使CStudent类具有以下特点: a.该类具有学生姓名、学号、程序设计、信号处理、数据结构三门课程的成绩; b.学生全部信息由键盘输入,以提高程序的适应性; c.通过成员函数统计学生平均成绩,当课程数量增加时,成员函数无须修改仍可以求取平均成绩; d.输出学生的基本信息、各科成绩与平均成绩; e.学生对象的定义采用对象数组实现; f.统计不及格学生人数。

13

C++面向对象程序设计实验指导书 实验四

实验四 类和对象—对象传递与静态成员

4.1 实验目的

1.理解静态成员(静态数据成员、静态成员函数)的作用与使用; 2.理解友元(友元函数、友元类)的作用于使用; 3.理解常类型的使用。

4.2 实验内容 4.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include #include

class CStudent {

public:

CStudent(char *n, int a); ~CStudent();

static void SetAge(int age);

private:

char *name; int age;

static int nTotalObj; };

int CStudent::nTotalObj = 0;

CStudent::CStudent(char *n, int a) :age(a) {

int nLen = strlen(n);

name = new char[nLen+1]; strcpy(name,n); name[nLen] = '\\0';

14

C++面向对象程序设计实验指导书 实验四

nTotalObj++; }

CStudent::~CStudent() {

delete[] name;

nTotalObj--; }

void CStudent::SetAge(int age) {

this->age = age; }

void main() {

CStudent stu1(\"张三\",25); CStudent str2(\"李四\",26);

cout<<\"CStudent::nTotalObj=\"<问题一:以上程序编译能通过吗,为什么?

问题二:成员变量nTotalObj在程序中起什么作用,它是如何实现的?

问题三:如果规定该程序的主函数和类CStudent中的成员变量的属性不允许改变,应该如何改正该程序?

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include #include

class CStudent {

public:

CStudent(char *n, int a); ~CStudent();

private:

char *name; int age; };

CStudent::CStudent(char *n, int a) :age(a) {

int nLen = strlen(n);

name = new char[nLen+1];

15

C++面向对象程序设计实验指导书 实验四

strcpy(name,n); name[nLen] = '\\0'; }

CStudent::~CStudent() {

delete[] name; }

class CTeacher {

public:

CTeacher(char *tn, int ta); ~CTeacher();

void SetStuAge(int a); private:

char *name; int age;

CStudent stu; };

CTeacher::CTeacher(char *tn, int ta) :age(ta) {

int nLen = strlen(tn);

name = new char[nLen+1]; strcpy(name,tn); name[nLen] = '\\0'; }

CTeacher::~CTeacher() {

delete[] name; }

void CTeacher::SetStuAge(int a) {

stu.age = a; }

void main() {

CStudent stu(\"张三\",25); CTeacher tea(\"李四\",26);

16

C++面向对象程序设计实验指导书 实验四

}

问题一:以上程序有两大错误,试指出来,并改正之?

3.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include \"iostream.h\" class Date {

private:

const int year; const int month; const int day; public:

Date(int y,int m,int d); void showdate(); };

Date::Date(int y,int m,int d) {

year = y; month = m; day = d; }

void Date::showdate() {

cout<void main() {

const Date obj(2007,10,30); obj.showdate(); }

问题一:以上程序有两大错误,试指出来,并改正之(要求主函数和类Date的数据成员属性不可以改动)?

4.2.2 程序设计

1.某商店经销一种货物。货物成箱购进,成箱卖出,购进和卖出时以重量为单位,各箱的重量不一样,因此,商店需要记录下目录库存的总重量。试用C++模拟商店货物购进和卖出的情况。

17

C++面向对象程序设计实验指导书 实验五

实验五 派生与继承—单重派生

5.1 实验目的

1.理解继承的含义以及声明;

2.理解共有派生、私有派生和保护派生的含义以及使用; 3.理解单派生类中构造函数和析构函数的调用顺序。

5.2 实验内容 5.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include \"iostream.h\"

class CBase {

public:

CBase(int a) :a(a) { } protected:

void print() { cout<<\"a=\"<class CDerive : public CBase {

public:

void print() { CBase::print(); cout<<\"b=\"<18

C++面向对象程序设计实验指导书 实验五

int b; };

void main() {

CDerive d; d.print(); CBase b; b.print(); }

问题一:以上程序有两大错误,试指出来,并改正之?

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include \"iostream.h\"

class CBase {

public:

CBase(int a) :a(a) { cout<<\"base structure\"<~CBase() { cout<<\"base destructure\"<void print() { cout<<\"a=\"<class CDerive : public CBase {

public:

CDerive(int a, int b,int c) :CBase(a),b(b),c(c) { cout<<\"derive structure\"<~CDerive() { cout<<\"derive destructure\"<19

C++面向对象程序设计实验指导书 实验五

}

void print() { CBase::print(); cout<<\"b.a=\"<CBase b; int c; };

void main() {

CDerive d(1,2,3); -----------------------------------------------------① d.print(); }

问题一:以上程序的输出结果是什么,说明为什么? 问题二:①处语句执行完后,d.b.a的值为多少?

5.2.2 程序设计

1.定义点CPoint类作为基类,在此基础上派生出直线CLine类和圆CCircle类,并要求基类和各派生类具有以下特点:

a.CLine类含有计算直线长度和斜率的成员函数; b.CCircle类含有计算圆面积的成员函数。

20

C++面向对象程序设计实验指导书 实验六

实验六 派生与继承—多重派生

6.1 实验目的

1.理解多重派生的定义;

2.理解多重派生中构造函数与析构函数的调用顺序; 3.理解多重派生中虚拟基类的作用;

6.2 实验内容 6.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

class CBase1 {

public:

CBase1(int a) :a(a) { cout<<\"base1 structure...\"<~CBase1() { cout<<\"base1 destructure...\"<void print() { cout<<\"a=\"<class CBase2 {

public:

CBase2(int b) :b(b) { cout<<\"base2 structure...\"<21

C++面向对象程序设计实验指导书 实验六

}

~CBase2() { cout<<\"base2 destructure...\"<void print() { cout<<\"b=\"<class CDerive : public CBase1, public CBase2 {

public:

CDerive() { cout<<\"derive structure...\"<~CDerive() { cout<<\"derive destructure...\"<void print() { CBase1::print(); CBase2::print(); b1.print(); b2.print(); cout<<\"c=\"<CBase1 b1; CBase2 b2; int c; };

void main() {

CDerive d; d.print(); }

问题一:改正以上程序中存在的错误,并分析该程序的输出结果。

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

22

C++面向对象程序设计实验指导书 实验六

#include \"iostream.h\"

class CBase {

public:

CBase(int a) :a(a) { } int a; };

class CDerive1 : public CBase {

public:

CDerive1(int a) :CBase(a) { } };

class CDerive2 : public CBase {

public:

CDerive2(int a) :CBase(a) { } };

class CDerive : public CDerive1,public CDerive2 {

public:

CDerive(int a,int b) :CDerive1(a),CDerive2(b) { } };

void main() {

CDerive d(1,2); cout<问题一:在不改变原有程序意图的前提下,分别用三种方法改正以上程序,并使程序正确输出。

23

C++面向对象程序设计实验指导书 实验六

6.2.2 程序设计

1.建立普通的基类building,用来存储一座楼房的层数、房间数以及它的总平方数。建立派生类house,继承building,并存储卧室与浴室的数量,另外,建立派生类office,继承building,并存储灭火器与电话的数目。设计一主函数来测试以上类的用法。

6.3思考题

1.按照下图的类层次结构编写程序,定义属于score的对c1以及类teacher的对象t1,分别输入个数据成员的值后再显示出这些数据。

personnameidstudaddrtelteacherdegreedepstudentoldsnomathengscore

24

C++面向对象程序设计实验指导书 实验七

实验七 多态性—函数与运算符重载

7.1 实验目的

1.理解动态联编和动态联编的概念; 2.理解掌握成员函数方式运算符重载; 3.理解掌握友元函数方式运算符重载; 4.理解掌握++、--、=运算符的重载。

7.2 实验内容 7.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include \"iostream.h\"

class CComplex {

public:

CComplex() { real = 0; imag = 0; }

CComplex(int x,int y) { real = x; imag = y; }

int real; int imag;

CComplex operator + (CComplex obj1)-----------------------------------------------① { CComplex obj2(real + obj1.real, imag + obj1.imag); return obj2; } };

25

C++面向对象程序设计实验指导书 实验七

void main() {

CComplex obj1(100,30); CComplex obj2(20, 30); CComplex obj;

obj = obj1+obj2; ------------------------------------------------------------------② cout << obj.real <问题一:①处的运算符重载,为什么该函数的返回值要设计成CComplex类型?

问题二:②处的运算符重载函数调用就相当于“obj=operator+(obj1,obj2);”,但是为什么CComplex类中的运算符重载函数只设计了一个参数?

2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include \"iostream.h\"

class CComplex {

public:

CComplex() { real = 0.0; imag = 0.0; }

CComplex(float x, float y) { real = x; imag = y; }

CComplex operator + (CComplex &obj1, CComplex &obj2) { CComplex obj3(obj1.real + obj2.real, obj1.imag + obj2.imag); return obj3; }

CComplex &operator++(CComplex &obj) { obj.real += 1; obj.imag +=1; return obj; }

void print() { cout<26

C++面向对象程序设计实验指导书 实验七

private:

float real; float imag; };

CComplex &operator--(CComplex &x) {

x.real -= 1; x.imag -= 1; return x; }

void main() {

CComplex obj1(2.1,3.2); CComplex obj2(3.6,2.5); cout<<\"obj1=\"; obj1.print(); cout<<\"obj2=\"; obj2.print();

CComplex obj3 = obj1 + obj2; cout<<\"befor++, obj3=\"; obj3.print(); ++obj3;

cout<<\"after++, obj3=\"; obj3.print(); --obj3;

cout<<\"after--, obj3=\"; obj3.print();

CComplex obj4 = ++obj3; cout<<\"obj4=\"; obj4.print(); }

问题一:以上程序中的三个运算符重载都有错误,试改正过来,并分析该程序的输出结果。

7.2.2 程序设计

1.把7.2.1中第一道题的程序改造成采取友元函数重载方式来实现“+”运算符,并采取友元函数重载方式增加前置和后置“++”以及“--”运算符重载,并设计主函数来验证重载运算符的用法。

27

C++面向对象程序设计实验指导书 实验七

7.3思考题

1.定义CPoint类,有两个成员变量:横坐标(x)和纵坐标(y),对CPoint类重载“++”(自增运算符)、“--”(自减运算符),实现对坐标值的改变。(每个函数均采用友元禾成员函数实现)

28

C++面向对象程序设计实验指导书 实验八

实验八 多态性—类型转换与虚函数

8.1 实验目的

1.理解掌握运算符[]、()的重载;

2.理解类型转换,掌握类型转换函数的设计和使用; 3.理解和掌握虚函数的作用;

4.掌握利用虚函数实现C++的运行时多态性; 5.理解纯虚类和抽象类。

8.2 实验内容 8.2.1程序阅读

1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。

#include #include \"stdlib.h\"

class CComplex {

public:

CComplex(double r = 0, double i = 0) { real = r; imag = i; }

int operator int() { return (int)real; }

void Display(void) { cout << \"(\" << real << \ << imag << \")\" << endl; }

protected:

double real; double imag; };

29

C++面向对象程序设计实验指导书 实验八

class CVector {

public:

CVector(CComplex &obj1, CComplex &obj2, CComplex &obj3, CComplex &obj4) { objArray[0] = obj1; objArray[1] = obj2; objArray[2] = obj3; objArray[3] = obj4; }

friend CComplex &operator[](CVector obj, int n); private:

CComplex objArray[4]; };

CComplex &operator[](CVector obj, int n) {

if(n<0 || n>3) { cout<<\"Out of range!\"<return obj.objArray[n]; }

void main() {

CComplex c1(1.1, 1.1); CComplex c2(2.2, 2.2); CComplex c3(3.3, 3.3); CComplex c4(4.4, 4.4);

CVector v(c1,c2,c3,c4);

v[0].Display(); v[1].Display(); v[2].Display(); v[3].Display();

v[0] = 5.5; ----------------------------------------------------------① v[1] = CComplex(6.6); -------------------------------------------② v[2] = int(CComplex(7.7)); --------------------------------------③ v[3] = int(CComplex(8.8,9.9)); ----------------------------------④

30

C++面向对象程序设计实验指导书 实验八

}

v[0].Display(); v[1].Display(); v[2].Display(); v[3].Display();

问题一:上述程序存在两大错误,在不修改主函数和程序原意的前提下,改正该程序中存在的错误。

问题二:①处的转换属于显式转换还是隐式转换,并解释该转换过程。 问题三:②处的转换属于显式转换还是隐式转换,并解释该转换过程。 问题四:解释③处的转换过程。 问题五:解释④处的转换过程。

8.2.2 程序设计

1.编写一个程序计算三角形、正方形和圆形的面积,要求抽象出一个基类base,在其中说明一个虚函数,用来求面积,并利用单接口,多实现版本设计各图形面积的方法。

8.3思考题

1.设计一个汽车类Motor,该类具有可载人数、轮胎数、马力数、生产厂家和车主五个数据成员,根据Motor类派生出Car类、Bus类和Truck类。其中Bus类除继承基类的数据成员外,还具有表示车厢节数的数据成员Number;Truck类除继承基类的数据成员之外,还具有表示载重量的数据成员Weight。每个类都具有成员函数Display,用于输出各类对象的相关信息。要求设计一个统一的显示相关信息的全局函数ShowInfo在主函数种调用,主函数中不直接调用类里面的Display函数。

31

C++面向对象程序设计实验指导书 实验九

实验九 模板类的构造

9.1 实验目的

1.理解和应用类模板和函数模板; 2.复习数据结构的相关知识;

3.学习用C++的编程思想实现链表类。

9.2 实验内容 9.2.1程序阅读

1.理解下面的动态数组类模板,它由一系列位置连续、任意数量相同类型的元素组成,其元素个数可在程序运行时改变,并完成该类中没有完成的成员函数(不允许改变已有代码),并设计主函数,实现对该模板类的功能测试。

#include #include

//容错处理

enum ErrorType {

invalidArraySize,memoryAllocatetionError,indexOutOfRang };

char *errorMsg[] = {

\"Invalid array size\",

\"Memory allocation error\", \"Invalid index\" };

template class Array {

private:

T* alist; int size;

void Error(ErrorType error) const;//输出错误信息 public:

Array(int sz=50);//构造函数

32

C++面向对象程序设计实验指导书 实验九

Array(const Array& X);//拷贝构造函数 ~Array(void);//析构函数

Array& operator=(const Array& rhs);//重载赋值运算符 T& operator[](int i);//重载下标运算符 int GetSize(void) const;//获取数组大小 void Resize(int sz);//重新设置数组大小 };

template

Array::Array(int sz) {

if(sz <= 0) Error(invalidArraySize); size = sz;

alist = new T[size]; if(alist == 0) Error(memoryAllocatetionError); }

template

Array::Array(const Array& X) {

int n = X.size; size = n;

alist = new T[n]; if(alist == 0) Error(memoryAllocatetionError); T* srcptr = X.alist; T* destptr = alist; while(n--) *destptr++ = *srcptr++; }

template Array::~Array() {

delete[] alist; }

template

Array& Array::operator=(const Array &rhs) {

int n = rhs.size; if(size != n) {

33

C++面向对象程序设计实验指导书 实验九

delete[] alist; alist = new T[n]; if(alist == 0) Error(memoryAllocatetionError); size = n; }

T* destptr = alist; T* srcptr = rhs.alist; while(n--) *destptr++ = *srcptr++; return *this; }

template

T& Array::operator[](int n) {

if(n < 0 || n > size-1) Error(indexOutOfRang); return alist[n]; }

void main() { }

9.2.2 程序设计

1.设计一个通用链表类,要求如下:

a.数据成员包含头指针、尾指针、链表中节点个数、顺序访问中当前节点指针和当前节点前一个节点的指针;

b.主要的成员函数包含:生成节点(在链表头、尾以及任意位置)、插入节点、删除节点、访问/修改节点、遍历链表,以及一些辅助函数等; c.能实现两个链表的复制;

d.能实现两个链表对象的赋值;

e.在测试程序中定义两个整型链表A和B,本别插入5个元素,然后把B中的元素加入A的尾部。

9.3思考题

1.根据数据结构和类模板知识,定义一个通用队列(先进先出)类并加以实现,编写主函数进行测试;

2.根据数据结构和类模板知识,定义一个通用栈(后进先出)类并加以实现,编写主函数进行测试。

34

C++面向对象程序设计实验指导书 实验十

实验十 C++的I/O流类库

10.1 实验目的

1.理解C++输入输出流类库;

2.掌握ios类中用于控制输入输出成员函数的使用; 3.掌握操纵符格式控制的使用;

4.掌握用户自定义数据类型的输入输出方式; 5.掌握文本文件和二进制文件的输入输出;

6.将C++输入输出流灵活应用到类和对象知识中。

10.2 实验内容 10.2.1程序阅读

1.阅读下列程序,然后上机运行验证输出结果,并回答下列问题。

#include \"iostream.h\"

void showflags(long f) {

long i = 0x8000; for(; i; i=i>>1) { if(i&f) cout<<\"1\"; else cout<<\"0\"; }

cout<void main() {

showflags(cout.flags());

cout<<\"x_width=\"<cout<<\"x_precision=\"<35

C++面向对象程序设计实验指导书 实验十

}

cout<<\"* * * x_width=10,x_fill= ,x_precision=4 * * *\"<cout<<123<<\" \"<<123.45678<<\" \"<<234.567<cout<<\"x_precision=\"<cout<<\"* * * x_width=10,x_file=&,x_precision=4 * * *\"<cout<<123<<\" \"<<123.45678<cout<<123<<\" \"<<123.45678<cout<<\"x_precision=\"<showflags(cout.flags());----------------------------------------------------------② cout.setf(ios::right|ios::unitbuf);

showflags(cout.flags());----------------------------------------------------------③

问题一:①处的输出结果是什么,为什么? 问题二:②处的输出结果是什么,为什么? 问题三:③处的输出结果是什么,为什么?

(提示:在x_flags变量中left=0x0002,right=0x0004,unitbuf=0x2000)

10.2.2 程序设计

1.采用预定义的输入输出操纵符格式控制改造10.2.1中第一题,使其达到相同的输出效果。 2.定义一复数类CComplex(类中含有实部real和虚部imag私有成员变量,都为double类型),重载输入运算符>>和输出运算符<<,使得该类可以直接通过输入输出运算符进行输入输出操作。

3.有一名为test.txt的文件,里面分两行分别存储了整数12345678和字符串abcdefg,设计两个完整的程序,第一个程序以文本文件的方式存取该文件,第二个程序以二进制的方式存取该文件,并比较以这两种方式存取该文件对文件本身有什么影响。

10.3思考题

1.设计一学生注册信息登记程序,该程序要求达到以下要求: a.学生信息包括姓名,学号,性别;

b.学生信息要求能够循环从键盘输入,如果输入0 0 0,则退出输入;

c.将所有输入的学生信息按文本文件的方式存储到一名为stureginfo.txt的文件中,文件中

36

C++面向对象程序设计实验指导书 实验十

存储信息的格式如下:

姓名:张三

学号:10521030146 性别:男

d.停止输入后,程序读出存储到stureginfo.txt文件中的所有信息,并显示在屏幕上。

37

C++面向对象程序设计实验指导书 实验十一

实验十一 C++程序、Windows程序和MFC

程序

11.1 实验目的

1.理解C++程序、Windows程序以及MFC程序之间的联系与区别; 2.理解Windows程序的消息机制;

3.学会应用VC++6.0的AppWizard创建基于MFC的Windows程序; 4.理解C++在MFC中的位置和作用。

11.2 实验内容 11.2.1 实验描述

1.理解C++程序、Windows程序和MFC程序的联系与区别 C++是面向对象编程语言中的一种,它具有封装性、继承性以及多态性三大特性,用C++语言写出来的程序需要借助编译器才能生成可执行的二进制代码,VC++6.0中具有能识别C++程序的编译器,所以VC++6.0可以用来作为C++程序的开发环境。 MFC(Microsoft Foundation Class)是微软公司开发出来的一套用于Windows程序开发的类库,MFC是建立在C++语言基础之上的,它利用C++语言的三大特性对自己进行了封装,极大地方便了用户在Windows上进行程序开发,同时MFC也借助AppWizard使开发者摆脱离了那些每次都必写基本代码,借助ClassWizard和消息映射使开发者摆脱了定义消息处理时那种混乱和冗长的代码段。 Windows程序与其他程序最大的不同之处在于使用消息机制,在Windows程序中所发生的一切都可以用消息表示,消息用于告诉操作系统所发生的事情。在MFC中遵循Windows的消息机制,MFC对消息的处理利用了消息映射的方法,所谓消息映射就是将消息与处理函数相联系,即当系统产生一条消息时,它能找到处理该消息的函数,该方法的基础是宏定义实现。 2.Windows系统是一个消息驱动的OS,可以从以下几个方面来理解Windows的消息机制:  消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。

当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单选中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。

 谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对

消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。

38

C++面向对象程序设计实验指导书 实验十一

 未处理的消息到那里去了:Windows系统为窗口编写了默认的窗口过程,这个窗口过程

将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不用处理,而是让系统自己去做默认处理。  窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识

一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时,消息就会通过窗口一的句柄被发送到窗口过程代码中。

 Windows系统的消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被

放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。

3.本次实验将利用MFC的应用程序向导(AppWizard)生成一个支持MFC的Windows程序,同时在生成应用程序的过程中理解不同设置对工程的影响。

11.2.2 实验步骤

1.启动VC++6.0开发环境,选择File|New菜单项,弹出如图11-1对话框。

图11-1

2.选择MFC AppWizard[exe],在Location文本编辑框中输入文件欲保存的目录位置,或单击省略号“...”按钮选择已有的目录;同时在Project name下面的文本编辑框中输入工程名称,本次实验我们的工程名称为MyTestProject,这时OK按钮被激活。该对话框中还有以下选项:(如图11-1)

 Create new workspace单选按钮:表示创建一个新的工作区,并将新项目添加到这个工

39

C++面向对象程序设计实验指导书 实验十一

作区。

 Add current workspace单选按钮:表示将项目添加到当前工作区,如果此时有多个工作

区,那么可以通过选中Dependency of复选按钮来选择当前项目需要添加到的工作区。 2.单击OK按钮,进入如图11-2所示的MFC AppWizard - Step 1对话框,该对话框主要有以下选项:

 What type of application would you like to current?你想要创建的应用程序有以下单选项

供选择:

 Single document:生成单文档应用程序。  Multiple document:生成多文档应用程序。

 Dialog based:生成基于对话框的应用程序(如计算器等)。

 Document/View architecture support?是否需要支持文档/视图结构,需要则选中该选项,

如果不需要,则应用程序中关于文件的打开、关闭、保存及文档/视图的相互作用等功能需要程序员自己实现。

 What language would you like your resources in?选择生成何种语言界面的应用程序,如

果需要中文界面,则选择如图11-2中的“中文[中国]”,本例中选择生成单文档的应用程序。

图11-2

3.单击Next按钮进入MFC AppWizard – Step 2 of 6对话框,如图11-3所示,该对话框用于支持数据库功能选项的选择,本例中选择None,下面分别为该对话框中的主要选项做一个简单介绍:

 What database support would you like to include?有四个单选项供选择:

 None:不支持数据库。

 Header files only:只生成头文件。

40

C++面向对象程序设计实验指导书 实验十一

 Database view without file support:没有文件支持的数据库视图。  Database view with file support:具有文件支持的数据库视图。

 If you include a database view, you must select data source:若选择具有数据库视图,则必

须选择一个数据源。

 Data Source按钮,单击它,则打开如图11-4所示的Database Option对话框,用于进行

数据库的选择,主要有以下选项:

 Datasource:数据源区域,有以下单选项:

 ODBC:指定数据源是ODBC数据库。  DAO:指定数据源是DAO数据库。

 OLE DB:指定应用与OLE DB 数据源连接。  Recordset type:记录集类型区域,有以下单选项:

 Snapshot:指定记录集为快照。

 Dynaset:指定记录集为动态记录集。  Table:指定记录集为一个表。

 Advanced:高级选项,选中该选项可以指定m_bCheckCacheForDirtyFields为true,

为数据库创建一个数据缓冲区以检测数据。

图11-3

41

C++面向对象程序设计实验指导书 实验十一

图11-4

4.单击Next按钮进入MFC AppWizard – Step 3 of 6对话框,该对话框用于选择OLE选项的复合文档,本例中不使用OLE特性,故采用默认设置None,并取消对ActiveX Controls的选择。如图11-5所示:

图11-5

5.单击Next按钮进入MFC AppWizard – Step 4 of 6对话框(如图11-6所示),该对话框用于选择应用程序图形界面的外观,如工具栏、状态栏以及打印预览功能、使用3D控制外观

42

C++面向对象程序设计实验指导书 实验十一

和在线帮助等。本例中采用默认的设置,下面对各选项的功能作一个简单描述:  Docking toolbar:为应用程序创建工具栏  Initial status bar:为应用程序创建状态栏

 Printing and print preview:使应用程序具有打印与预览功能  Context-sensitive Help:具有支持上下文帮助的帮助文件  3D controls:使应用程序具有三维效果

 MAP[Messaging API]:使应用程序能够创建、操作、和存储邮件信息  Windows Sockets:支持基于TCP/IP的网络通信  Normal:普通外观

 Internet Explore ReBars:与IE相似的外观

图11-6

6.单击Next进入MFC AppWizard – Step 5 of 6对话框(如图11-7所示),该对话框用于设置以下三方面的内容:

 What style of project would you like?应用程序的主窗口是MFC风格还是窗口左边具有切

分窗口的浏览器风格

 Would you like to generate source file comments?在源文件是否加入注释以帮助用户编写

程序代码

 How would you like to use the MFC library?使用动态链接库还是静态链接库 本例中选择As a statically linked library选项,其它接受默认设置。

43

C++面向对象程序设计实验指导书 实验十一

图11-7

7.单击Next按钮进入MFC AppWizard – Step 6 of 6对话框(如图11-8所示),该对话框用于对默认类名、基类名、各类文件名进行修改。如果选用CEditView类作为基类,这样生成的视图类将自动与文档类互相配合,其功能可以与Notepad相比,本例采用默认设置。

图11-8

44

C++面向对象程序设计实验指导书 实验十一

8.单击Finish按钮,生成如图11-9所示的New Project Information信息框,在该框信息框中列出了将要创建的应用程序的相关信息。单击OK按钮,完成应用程序的创建,若不满意,可以单击Cancel按钮,返回前面步骤进行修改。

图11-9

9.完成应用程序创建后,可以通过选择Build->Build MyTestProject.exe来完成对该工程的编译、链接工作,编译链接完成后,输出窗口中会输出警告信息和错误信息。

10.最后可以通过选择Build->Execute MyTestProject.exe(或Ctrl + F5)来运行该应用程序,如果前面的设置正确,并且VC++6.0开发环境安装正确,那该程序就可以正确运行。

11.2.3 实验结果分析

1.运行以上生成的应用程序后,就可以看到如图11-10所示的应用程序界面,该界面具有Windows应用程序的大部分特点(如窗口界面,菜单,工具栏以及状态栏等),但是该程序只是一个框架,并不能真正完成用户需要的工作,而我们要做的就是在这个已有的框架的基础上添加自己的代码来完成相关的工作。

45

C++面向对象程序设计实验指导书 实验十一

图11-10

2.VC++6.0以三种方式来组织文件(如图11-11):ClassView、ResourceView和FileView,其中ResourceView用来管理应用程序中用到的所有资源(包括对话框、位图、图表、菜单、工具栏等);ClassView和FileView管理着相同的文件,其中ClassView以类为单位查看文件,FileView以文件名为单位查看文件,这两者之间的联系就在于:VC++6.0中所有的类声明和类定义都是分开来的,其中类声明存放在头文件(文件后缀名为.h)中,类的定义存放在源文件(文件后缀名为.cpp)中。通过双击FileView中的文件可以在工作空间中显示相应文件的内容,通过双击ClassView中的类名称或类下面的成员变量可以在工作空间中显示对应类声明的头文件,通过双击ClassView中类下面的成函数可以在工作空间中显示对应类声明的源文件。

项目区 工作空间 VC++6.0组织文件的三种方式

图11-11

46

C++面向对象程序设计实验指导书 实验十一

11.3思考题

1.本实验的工程中一共生成了多少个类,它们的基类分别是什么,这些类的信息分别存储在哪些文件中?

2.本实验的工程中有一个名为CMainFrame的类,请问该类中有哪些成员函数和成员变量,成员变量中哪些属于类对象?

3.试分析类CAboutDlg在本实验的工程中所起的作用。

47

C++面向对象程序设计实验指导书 实验十二

实验十二 简单单文档MFC程序设计

12.1 实验目的

1.学会利用AppWizard生成单文档工程; 2.理解单文档工程中类的组织结构及其作用; 3.初步了解MFC的文档/视图结构; 4.初步理解键盘消息的相应;

5.初步理解和学会菜单消息的添加。

12.2 实验内容 12.2.1 实验描述

1.MFC中的消息种类 MFC中的消息可以分为Windows消息、控件通知消息、定时消息和命令消息等。

 Windows消息:通常指以WM开头的消息,但是WM_COMMAND除外,键盘消

息和鼠标消息都是属于Windows消息,由窗口和视图进行处理。Windows消息通常带有若干个参数传递给消息处理函数,这些参数为处理函数正确地处理消息提供了充分的信息。

 控件通知消息:指当控件的状态发生改变时,控件向其父窗口发送的消息,MFC

将消息传递给相应的窗口处理。MFC对控件通知消息的传递方式与其它以WM开头的Windows消息一样,但是BN_CLICKED例外,该消息的传递方式与命令消息的传递机制相同。

 定时消息:当用户需要应用程序每隔一个指定的时间间隔便执行某一特定的操作

时,就需要用到定时消息WM_TIMER。

 命令消息:命令消息来自于用户界面对象的WM_COMMAND消息,这些用户界

面包括菜单、工具栏按钮和快捷键等。

2.MFC消息的映射机制 消息映射是指将消息与处理函数相联系,即当系统产生一条消息时,它能找到处理该消息的函数。VC++6.0提供了多种消息映射宏用于消息映射,如表12-1

表12-1 Visual C++常用消息映射宏 消息映射宏 BEGIN_MESSAGE_MAP END_MESSAGE_MAP ON_COMMAND ON_COMMAND_RANGE 功能 表示消息映射的开始,用于源文件中 表示消息映射结束,用于源文件中 将特定的命令消息映射到类的成员函数 将一组特定的命令消息映射到类的成员函数 DECLARE_MESSAGE_MAP 在头文件中使用,用于声明在源文件中存在消息映射

2.MFC中的文档/视图结构(document/view Architecture)

48

C++面向对象程序设计实验指导书 实验十二

文档视图结构(Document/View)是MFC的精髓,也是Observer模式的具体实现框架之一,Document/View Architecture通过将数据和其表示分开,提供了很好的数据层次和表现层次的解耦。MFC的文档/视图结构它只是一个模型,它为程序员提供了一个基础性的平台,通过这个平台,程序员可以实现自己相应的功能。同时文档/视图结构它还是一个由内部有联系的事物所组成的一个有机的整体。从程序的角度来看,文档/视图结构主要通过四个类来实现的:文档模板类、文档类、视图类和框架窗口类(这点从后面的实验中可以得到进一步体现)。

12.2.2 实验步骤

1.建立一个名称为Exp12的MFC单文档工程,其它选项保留默认值(参照实验十一中的各项设置),编译,运行,运行后的界面如图12-1所示:

图12-1

下面对该工程中自动生成的类做一个简单介绍:  应用程序类(CExp12App)

应用程序类CExp12App由CWinApp类派生而来,该类的每一个对象代表一个应用程序,程序中默认定义了一个全局对象theApp。CExp12App类的功能是管理整个应用程序,负责程序的启动,初始化,窗口的创建以及从Windows中获取消息并将消息分发到适当的目的地。

 主框架窗口类(CMainFrame)

本应用程序的主框架窗口类名为CMainFrame,它由CWnd的一个子类CFrameWnd派生而来。CMainFrame类是一个顶级、可重叠、可改变大小的窗口。CMainFrame类管理主框架窗口,并拥有一些如菜单、工具栏和状态栏等控件,同时它还扮演转发菜单和

49

C++面向对象程序设计实验指导书 实验十二

工具栏消息的角色。

 文档类(CExp12Doc)

本应用程序文档类名为CExp12Doc,从MFC的CDocument类派生而来,文档类的主要作用是保存应用程序的数据,并提供磁盘文件操作。直接由AppWizard生成的文档类还不能做太多的工作,毕竟AppWizard创建的应用程序并不知道是字处理程序还是绘图程序,或是其它的程序。用户需要修改文档类,增加成员变量以存储应用程序的数据,增加成员函数以获得和修改数据,然后为应用程序服务。  视图类(CExp12View)

本应用程序视图类名为CExp12View,默认的视图类是CView的一个子类,而CView又是CWnd的子类。视图类的主要工作是管理视图窗口,负责用户数据的输入和数据的输出显示。它的基类可以在创建工程的时候进行修改,从而获取一些MFC已有的通用的功能。  其它文件

除了以上介绍的类之外,AppWizard还会自动生成StdAfx.cpp和StdAfx.h两个文件,这两个文件是每个基于MFC程序所必需的,用于建立一个预编译头文件*.pch和一个预定义的类型文件StdAfx.obj。MFC是一个功能强大的类库,包含很多头文件,如果每次都编译则比较费时,因此将afxwin.h、afxext.h、afxcmm.h和afxdisp.h都放在StdAfx.h文件中,这样编译系统可以识别哪些文件已经编译过,因此采用预编译头文件可以加速应用程序的编译过程。 2.添加键盘消息响应 理解了上述内容后,我们来实现我们今天实验的第一个消息响应功能,即响应用户的键盘消息,然后将用户在键盘上按下的字符和数字显示在上面工程的视图中。从上面的文档/视图结构知识中我们知道,视图类主要是用来显示数据,文档类主要是用来存储数据,所以本实验的大部分工作都是在视图类中完成的。

 为了存储用户每次在键盘上按下的字符或数字,我们首先需要定义一个视图类的成

员变量来存储用户按下的键盘内容,找到视图类CExp12View的类声明文件Exp12View.h,然后在该文件的类声明中加上CString m_strShowContent; 此处类CString是MFC中用来存储和管理字符串的类,它提供了对字符串的一系列方便的操作(如图11-2)。

图11-2

50

C++面向对象程序设计实验指导书 实验十二

工程名称  然后我们添加响应键盘消息的消息映射函数:打开视图类CExp12View的实现文件

Exp12View.cpp,在工作空间中右击选择[ClassWizard],然后进入如图11-3所示的类向导对话框中,按图示选择好类和对象ID以及需要增加的消息类型(此处的WM_CHAR消息即为键盘消息),然后单击[Add Function],然后单击[Edit Code]进入相应的消息响应函数中编辑代码。 类名称 对象ID, 第一个为当前类名 对应对象下所有能响应的消息名称 对应消息的消息映射函数名称

图11-3

 在WM_CHAR的消息映射函数OnChar()中按照如图11-4添加代码,其中的if语

句用于判断用户的键盘消息是否是通过按下字符或数字发送过来的,然后将按下的键盘字符代码转化成CString类型存储起来,最后通过调用Invalidate()和UpdateWindow()重新刷新屏幕,调用Invalidate()和UpdateWindow()后系统会立即发送WM_PAINT消息并刷新屏幕,WM_PAINT消息执行过程中会调用视图类的OnDraw()函数重画视图。

图11-4

51

C++面向对象程序设计实验指导书 实验十二

 最后需要在屏幕上显示键盘上按下的内容,即成员变量m_strShowContent中

存储的内容,前面提到用户按下键盘上的字符或数字后,需要调用Invalidate()和UpdateWindow()来刷新屏幕,而Invalidate()和UpdateWindow()的调用会导致系统调用视图类中的OnDraw()函数来重画视图,所以我们的显示工作就在视图类的OnDraw()函数中进行,此处可以直接利用OnDraw()中传过来的参数pDC的成员函数TextOut在坐标为(0,0)的地方显示m_strShowContent中的内容,如图11-5所示。

图11-5

3.添加菜单消息响应 菜单的基本属性主要包括标识符(ID)、标题(Caption)和提示(Prompt)三大要素,标识符用来在程序中唯一标识菜单项,标题是实际显示在菜单上的文字信息,提示是用户在查看某个菜单时,显示在窗口底端的文字信息。当我们选择菜单后,Windows会向应用程序发出一个WM_COMMAND消息,为了处理菜单消息发出的命令消息,MFC消息机制会扫描应应用程序的所有类,查找可以处理该命令消息的类,这种方法叫做命令子程序,只适用于WM_COMMAND消息,当使用了命令子程序后,WM_COMMAND消息首先被发送到当前活动的视图,之后发送到该视图的文档,然后是主框架窗口,最后到达应用程序本身。添加菜单消息分为三步:

 添加菜单资源:将程序的左视图定位到资源视图上,然后选择[Menu],双击

[IDR_MAINFRAME],程序的工作空间中将显示当前工程使用的菜单资源,定位到[查看]->[工具栏]上,然后在键盘上按[insert]键,这时将在当前位置新增一空白菜单,双击该空白菜单,将弹出如图11-6所示的菜单属性编辑对话框,按图示填写。

52

C++面向对象程序设计实验指导书 实验十二

图11-6

 添加菜单消息响应:将工程切换到显示视图类定义文件中,在工作空间中右击鼠标,

选择[Class Wizard],系统将弹出如图11-7所示的对话框,在Object IDs中选中刚才添加的菜单ID,也就是ID_SHOW_MESSAGE,然后在Messages中选择COMMAND,单击[Add Function],在弹出来的对话框中单击[Ok],然后选择[Edit Code]进入消息映射函数进行代码编辑。

图11-7

 进入消息映射函数进行代码编辑后,我们需要做的就是根据不同的需求添加我们自

己的代码了。本实验中我们通过调用MFC中的全局函数AfxMessageBox弹出一段文字信息,如图11-8所示:

图11-8

53

C++面向对象程序设计实验指导书 实验十二

12.2.3 实验结果

由键盘输入的内容 1.完成键盘消息响应后,程序的运新结果如图11-9所示:

图11-9

2.完成菜单消息响应后,用户选择菜单[显示消息],程序的运行结果如图11-10所示:

图11-10

54

C++面向对象程序设计实验指导书 实验十二

12.3思考题

1.MFC的文档/视图结构中的文档和视图的功能是如何分工的,为什么本实验中的键盘输入内容显示工作要在视图的OnDraw()中来完成?

2.当系统收到一个菜单消息时,文档类,视图类,主窗口框架类和应用程序类这四个类分别收到这个消息的次序是怎样的?

3.实验中用到的两个函数Invalidate()和UpdateWindow()的作用是什么?

55

C++面向对象程序设计实验指导书 实验十三

实验十三 简单对话框程序设计

13.1 实验目的

1.学会利用AppWizard生成基于对话框工程; 2.理解基于对话框工程中类的组织结构及其作用; 3.学会在对话框上添加和使用简单控件; 4.学会在单文档工程中显示模态简单对话框。

13.2 实验内容 13.2.1 实验描述

在Windows应用程序中,对话框被用来作为程序和用户之间交互的工具。对话框可以按照其动作模式分为模式和无模式两大类,MFC的对话框类(CDialog)既支持模式对话框也支持无模式对话框。对于模式对话框,在同一个应用程序中,只有该对话框被关闭后,对程序的其它功能进行操作,这是因为,当模式对话框被打开后,对话框就接管了父窗口的输入控制权;而对于无模式对话框,对话框与父窗口共享控制权,用户可以在主窗口和对话框之间进行来回切换,在对话框仍保留在屏幕上的同时,用户还可以在应用程序的其他窗口中进行操作。

本实验有两部分内容:一为利用MFC应用程序向导直接建立一个基于对话框的工程,然后在该对话框上三个编辑框中分别输入三个整数,通过单击一计算按钮算出三个数当中最大的那个,并在另外一个编辑框中显示计算结果;一为建立一单文档应用程序,然后学会在单文档工程中弹出模式对话框的方法。

13.2.2 实验步骤

1.普通对话框程序的设计

 建立一基于对话框的应用程序,工程名称为Exp13_1,其它设置保留默认值,和实

验十二不一样,因为基于对话框的应用程序没有文档/视图结构,所以本实验的工程包括的主要类有应用程序类(CExp13_1App)和对话框类(CExp13_1Dlg),其中应用程序类主要用来管理整个程序开始和关闭,对话框类用来管理程序的主窗口(在基于对话框的工程中,应用程序的主窗口就是对话框)中所有的工作。编译、运行程序,程序的运行结果如图13-1所示:

56

C++面向对象程序设计实验指导书 实验十三

图13-1

 打开左视图中的资源视图,展开[Dialog],双击IDD_EXP13_1_DIALOG,工作空

间中将显示主窗口对话框,编辑该对话框(需要哪个控件就在工作空间右边的Contros对话框对应的控件上按住鼠标左键,并拖到对话框界面上,然后释放鼠标左键,不需要哪个控件就在对话框界面上选上该控件,然后按键盘的[Delete]键删除,添加控件时,参照表13-1中的控件类型),使对话框上面的控件布置如图13-2。  修改对话框上面控件的属性:选中某一控件,然后右击,选择[Properties],然后在

弹出的对话框中按照表13-1设置对话框中所有控件的属性。

图13-2 表13-1

控件类型 Static Text Static Text Static Text Static Text Edit Box Edit Box Edit Box ID IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_NUMBER1 IDC_NUMBER2 IDC_NUMBER3 Caption 请输入整数1: 请输入整数2: 请输入整数3: 最大值为: 57

对应变量名称 m_nNum1 m_nNum2 m_nNum3 int int int 变量类型 C++面向对象程序设计实验指导书 实验十三

Edit Box Button Button IDC_MAX_NUM ID_MAX IDCANCEL 求最大值 关闭 m_nMaxNum int  添加对话框控件成员变量:对话框控件成员变量分为两种类型的,一种是控制(Control)类型,一种是值(Value)类型的。任何一种控件都有相对应的MFC类来对该控件做相应的管理,定义了一个控制类型的变量就相当于定义了这种控件对应类的一个对象,并且这个对象和对话框上相应的控件相关联起来了,而值类型的变量值是用来存储在该控件界面上显示的值,或是把变量里面的内容显示到控件界面上。本次实验中添加的变量全部为值类型的。具体做法为:在对话框界面上右击鼠标,选择[ClassWizard],点击[Member Variables]页,选中相应的ID值,然后单击[Add Variable],然后在弹出的对话框中输入变量名称,和选择变量类型,如图13-3所示,重复上面的操作继续添加成员变量,使得表13-1中的变量全部添加完毕。

图13-3

 添加控件响应函数:通过前面的描述我们不难知道此处我们需要添加两个按钮控件

的鼠标单击响应函数(表示当用户点击了按钮后要做相应的处理),具体做法如下:在Exp13_1Dlg.cpp文件中右击鼠标,选择[ClassWizard],然后在弹出的对话框中找到相应的控件ID(如图13-4所示),然后选中BN_CLICKED消息,单击[Add Function],在弹出的对话框中单击[OK],重复上面的操作添加另外一个控件的鼠标单击事件。

58

C++面向对象程序设计实验指导书 实验十三

图13-4

 添加消息响应函数代码:将工作空间中显示的内容切换到Exp13_1Dlg.cpp,定位

到上面添加的两个消息响应函数上,添加控制代码,如图13-5所示:

图13-5

 到目前为止,程序基本完成,可以编译运行了。 2.模式对话框的建立

按照前面的描述,对话框分为模式对话框和非模式对话框,上一个实验我们建立了一个模式对话框,而且这个对话框就是整个程序的主界面,本次实验我们将学习如何在单文档工程中弹出我们自己定义的对话框,这种应用在通常的应用程序中应用的非常普遍。

一个模式对话的显示主要分为三步,第一步就是对话框资源的编辑,即该对话框的外观,

59

C++面向对象程序设计实验指导书 实验十三

用户可以根据功能的需要在对话框界面上;第二步就是建立该对话框对应的类,在MFC中,任何一个对话框都需要建立相应的类来管理和组织该对话框,对话框中实现的功能就是在该类的相应函数中完成的;第三步就是在需要显示对话框的地方建立一个该对话框类的对象,然后调用该的成员函数DoModal()显示该对话框。以下是具体的操作步骤:

 利用MFC的AppWizard建立一个单文档工程,工程名称为Exp13_1,其它选项保

留默认值。

 参照12.2.2中的“添加菜单消息响应”操作过程,添加一菜单,菜单位置和属性设

置参照图13-6

图13-6

 同样参照12.2.2中的“添加菜单消息响应”操作过程,为刚才添加的菜单在

CMainFrame的MainFrm.cpp中添加消息响应函数,如图13-7所示:

图13-7

60

C++面向对象程序设计实验指导书 实验十三

 添加对话框资源:在项目区中定位到资源视图页,然后点击[Dialog],右击选择[Insert

Dialog],然后系统会自动增加一个ID为IDD_DIALOG1的对话框,程序员可以在右边显示的对话框界面添加自己需要的控件,本次实验我们的任务就是通过选择菜单后弹出该对话框,对话框本身并不做任何工作,所以我们保留对话框界面的初始状态,如图13-8所示:

图13-8

 在刚才新添加的对话框界面上双击鼠标,由于该对话框还没有建立相应的类,所以

系统会自动弹出是否新建对话框类的提示,如图13-9所示:

图13-9

61

C++面向对象程序设计实验指导书 实验十三

 单击[OK]按钮,系统进入创建对话框类下一步,输入对话框类名称CMyDialogDlg

后单击[OK],如图13-10所示:

图13-10

 单击[OK]关闭ClassWizard对话框,到这里为止,对话框类建立完成。

 将工作空间中显示的内容切换回到刚才添加菜单消息响应函数的内容,即

MainFrm.cpp中的OnShowDialog()函数,然后在该函数中添加模式对话框的显示代码,由于这个地方拥到了刚才建立的对话框类,所以就需要在MainFrm.cpp前面包含对话框类的头文件,即MyDialogDlg.h,添加后的代码如图13-11所示:

图13-11

62

C++面向对象程序设计实验指导书 实验十三

 自此,本工程程序设计完成,编译,运行程序,查看结果。

13.2.3 实验结果

1.对于实验一,程序运行界面如图13-12所示,当用户在左边三个编辑框中输入整形数据后,单击[求最大值]按钮,程序则会求出三个输入数中最大的那个,并且显示在右边的编辑框中。

图13-12

2.对于实验二,运行程序,然后点击添加的菜单[显示模态对话框]后,程序弹出在程序中新建的对话框,如图13-13所示

图13-13

13.3思考题

1.在实验一中和对话框(在本工程中也就是主窗口界面)资源相对应的类名称叫什么,并找出该类中用于初始化该对话框的消息响应函数的名称,分析该初始化函数中做了哪些工

63

C++面向对象程序设计实验指导书 实验十三

作。

2.实验二中默认弹出的对话框什么工作也没有做,改造该程序,使弹出来的对话框实现实验一中相应对话框的功能。

64

C++面向对象程序设计实验指导书 实验十四

实验十四 简单数据库程序设计

14.1 实验目的

1.理解Windows中的数据库访问技术(ODBC/ADO); 2.理解MFC中相应的ODBC类的作用和使用; 3.学会简单数据库程序的设计过程。

14.2 实验内容 14.2.1 实验描述

数据库是一个与特定主题或目的的相关联的数据集合,这个数据集合又可以进一步组成各种“表”,表用列和行来给出特定项目的信息。 DBMS(数据库管理系统)是一套程序,用来定义、管理和处理数据库与应用程序之间的联系,例如FoxPro、Access、Sybase等都是DBMS。 SQL(Structured Query Language,结构化查询语言) 最早由IBM提出,是专门用来处理关系数据库的基于文本的语言。SQL向数据库提供了完善而一致的接口,它不是独立的计算机语言,需要DBMS的支持方能执行。SQL是一种标准的数据库语言,目前大多数DBMS都支持它。 VC6.0提供了ODBC、DAO和ADO等多种数据库访问方式。ODBC(Open DataBase Connectivity)即开放数据库连接,为各种类型的数据库管理系统提供了统一的编程接口,用户可以轻松自如地在应用程序中进行跨数据库的操作,再也不用担心种类繁多的数据库接口;DAO(Database Access Object)使用Microsoft Jet数据库引擎来访问数据库;ADO(Active Data Object)即活动数据对象,是微软为数据库应用程序开发推出的新的数据库访问技术,它是一组基于组件对象模型的自动化接口(IDispatch)技术,它以对象链接和嵌入的数据库(OLE DB)为基础,利用它可以快速地创建数据库应用程序。本实验将讨论ODBC技术在MFC中的使用,MFC的ODBC类对较复杂的ODBC API进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解ODBC API和SQL的具体细节,利用ODBC类即可完成对数据库的大部分操作。MFC的ODBC类主要包括: CDatabase类:主要功能是建立与数据源的连接。 CRecordset类:该类代表从数据源选择的一组记录(记录集),程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中。通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。 CRecordView类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(DDX)在记录集与表单视图的控件之间传输数据。该类支持对记录的浏览和更新,在撤销时会自动关闭与之相联系的记录集。 CFieldExchange类:支持记录字段数据交换(DFX),即记录集字段数据成员与相应的

65

C++面向对象程序设计实验指导书 实验十四

数据库的表的字段之间的数据交换。 CDBException类:代表ODBC类产生的异常。 概括地讲,CDatabase针对某个数据库,它负责连接数据源;CRecordset针对数据源中的记录集,它负责对记录的操作;CRecordView负责界面,而CFieldExchange负责CRecordset与数据源的数据交换。 本次实验将建立一个基本的人事(工资)管理数据库,要求实现数据表的显示、添加、修改和删除功能。

14.2.2 实验步骤

1.数据库及其表的建立 首先应用Microsoft Access建立一个人力资源数据库HrMan,然后在该数据库中建立一张名为Employees的表,选择路径保存好。表结构以及表数据分别如表14-1和图14-1所示:

表14-1 字段名称 Emp_id Emp_name Sex Title Wage Dep_id 描述 员工号 员工姓名 性别 职务 薪水 部门号 字段类型 int 文本 文本 文本 float int 50 2 50 字段大小 是否为空 否 否 否 否 否 否 是否主键 是 否 否 否 否 否

图14-1

2.连接ODBC数据源 数据库建立好后,我们就可以在ODBC中连接数据源了,具体操作如下:开始-->设置-->控制面板,双击[管理工具],在弹出的对话框中双击[数据源(ODBC)],在弹出的对话框中选择[系统DSN]页面,然后单击[添加]按钮,在弹出的对话框中按如图14-2所示选择,点击[完成]按钮,在弹出的对话框中输入数据源名称为TestDB,然后点击[选择(S)…](如图14-3所示),在弹出的对话框中找到上一步创建的数据库文件(文件后缀名位mdb),然后点击[确定],在点击[确定] -->[确定]完成ODBC数据源的连接。

66

C++面向对象程序设计实验指导书 实验十四

图14-2

图14-3

3.创建数据库应用程序 利用MFC的AppWizard创建一个名为Exp14的单文档工程,在第二步中选择“Database view without file support”,然后选择[Data Source…]按钮,在弹出的对话框的ODBC下拉框中选择上面我们添加的ODBC数据源TestDB(如图14-4所示),然后点击[OK],在弹出的“Select Database Tables”对话框中选择表Employees,然后点击[OK]完成数据源的设置,其它选项保留默认值,单击[Finish]完成工程的创建。

67

C++面向对象程序设计实验指导书 实验十四

图14-4

4.工程结构分析:以上工程具有MFC的文档/视图结构,所以本工程仍然包括文档/视图中的四个基本类:应用程序类(CExp14App)、主框架窗口类(CMainFrame)、文档类(CExp14Doc)和视图类(CExp14View)。这四个类的功能和前面讲到一致:应用程序类负责程序的初始化等工作,主框架窗口类负责整个应用程序的窗口布局管理,文档类负责数据的存储,视图类负责数据的显示工作;除了这四个类之外,本工程中还有一个非常重要的类就是数据集合CExp14Set,在本工程中,CExp14Set负责连接数据源和创建数据集。在文档类中有一个CExp14Set的成员对象,在创建文当对象的时候就会创建CExp14Set对象,所以CExp14Set的构造函数(实际上是通过调用基类的构造函数)负责连接数据源和创建数据集。整个系统的初始化流程图如图14-5: 必须先实例实例化集合类时负责程序的启动、 化成员对象调用集合类基类初始化、窗口的创 的构造函数连接m_exp14S建以及从 Windows数据源并创建集et 中获取消息,并将 合数据 消息分发到适当的 目的地 程序启动实例化应用程序类开始实例化文档类实例化集合类实例化文档类实例化主框架窗口类实例化视图类初始化结束 图14-5

5.关联并显示数据库信息:通过上面的分析我们知道,程序启动后已经连接好了数据库,并且创建了数据集(也就是从数据库中把记录全部取出来了),存储在文档类的成员对象m_exp14Set之中,接下来事情就是在视图类中把相关信息显示出来,显示工作可以通过MFC的数据交换功能来实现,具体做法如下:

68

C++面向对象程序设计实验指导书 实验十四

 编辑显示视图界面:从资源视图中打开对话框IDD_EXP14_FORM,在对话框中添

加需要显示的和表字段对应的控件,使之如图14-6所示(此处的编辑框只允许浏览数据库记录,不允许编辑,所以所有的编辑框都设置成只读的,即将编辑框的属性Disabled钩选上),对话框中各控件属性如表14-1所示:

图14-6

表14-1 控件类型 Static Text Static Text Static Text Static Text Static Text Static Text Edit Box Edit Box Edit Box Edit Box Edit Box Edit Box Button Button Button ID Caption 对应变量名称 变量类型 Disabled true true true true true true IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_EMP_ID IDC_EMP_SEX 员工编号: 员工姓名: 员工姓别: 员工职位: 员工薪水: 部门编号: IDC_EMP_NAME IDC_EMP_TITLE IDC_EMP_WAGE IDC_DEP_ID IDC_ADD IDC_MODIFY IDC_DELETE 新增 修改 删除 m_pSet->m_Emp_id m_pSet->m_Emp_name m_pSet->m_Sex m_pSet->m_Title m_pSet->m_Wage m_pSet->m_Dep_id  添加控件变量:此处的添加控件变量和前面讲到的添加控件变量有所不一样,前面讲到了程序初始化完成后,文档类的成员对象m_exp14Set中就已经存储了所有当前连接表的记录集了,所以此处添加控件的成员变量不是新增成员变量,而是将m_exp14Set中的数据成员和当前的控件关联起来就可以了。进一步观察程序就能发现CExp14View的中同样定义了一个CExp14Set类的成员指针变量m_pSet,并且该指针在视图类CExp14View初始化的时候(即调用函数CExp14View::OnInitialUpdate())就指向了文档类中的成员对象m_exp14Set,也就是说实际上程序初始化后视图类中的成员指针变量m_pSet就已经指向了当前连接

69

C++面向对象程序设计实验指导书 实验十四

的数据库表中的数据集,具体的添加控件成员变量步骤如下,在CExp14View工作空间中右击,选择[ClassWizard],在弹出的对话框中定位到[Member Variables]页,选中IDC_EMP_ID,然后单击[Add Variable]按钮,在弹出的对话框中单击下拉键头,选择m_pSet->m_Emp_id(如图14-7所示),然后单击[OK]按钮完成该控件的成员变量的添加,重复上述步骤,使得成员变量添加如表14-1所示。

图14-7

 编译,运行程序:到目前为止程序已经能够将数据库中的表的数据显示在界面中相

应的控件中了,并且能够通过CRecordView内嵌的功能实现数据库表记录的滚动浏览。

6.添加数据库表记录的新增功能:主窗口视图只能浏览数据库信息,要新增记录,需要另外弹出一个对话框让用户输入新增的信息,实现数据库表记录的新增首先需要新增一对话框。

 切换到资源视图,在[Dialog]上右击,选择[Insert Dialog],在显示的新增对话框资

源上右击,选择[Properties],将该对话框的ID修改为IDD_ADD_MODIFY_DLG,Caption修改为:新增/修改员工信息,字体选择9号宋体(保持和主界面视图字体一致)。在该对话框上增加控件,使得该对话框界面如图14-8所示:

图14-8

70

C++面向对象程序设计实验指导书 实验十四

 新增对话框类:在对话框上双击鼠标,在弹出的对话框上单击[OK],然后输入对

话框类名称CAddModifyDlg,单击[OK],再单击[OK]完成对话框类的创建。  修改对话框控件属性和新增控件成员变量,使得如表14-2所示:

表14-2 控件类型 Static Text Static Text Static Text Static Text Static Text Static Text Edit Box Edit Box Edit Box Edit Box Edit Box Edit Box Button Button ID IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_STATIC IDC_EMP_ID IDC_EMP_NAME IDC_EMP_SEX IDC_EMP_TITLE IDC_EMP_WAGE IDC_DEP_ID IDOK IDCANCEL Caption 员工编号: 员工姓名: 员工姓别: 员工职位: 员工薪水: 部门编号: 确定 取消 对应变量名称 变量类型 m_nEmpId m_strEmpName m_strEmpSex m_strEmpTitle m_fEmpWage m_nDepId int CString CString CString float int  新增按钮消息响应函数:切换到主视图对话框IDD_EXP14_FORM,双击[新增]按钮,系统提示输入新增消息响应函数名称,保留默认值,单击[OK]按钮,系统自动转到工作空间中刚才添加的消息响应函数处,在该消息响应函数中如图14-9添加函数代码,因为在其中用到了类CAddModifyDlg,所以必须在该文件的开头处添加包含头文件AddModifyDlg.h的代码。

图14-9

71

C++面向对象程序设计实验指导书 实验十四

 自此,添加数据库记录功能完成,编译,运行程序,测试该功能。

7.添加数据库表记录修改功能:主窗口视图中不能对数据库记录进行编辑,所以我们同样需要弹出另外一个对话框来对数据库表记录进行编辑,由于此处修改数据的功能和前面添加数据的功能相似,所以这里我们重用前面建立的对话框。

 添加修改按钮消息响应函数:具体操作和前面的添加新增按钮消息响应函数一样。  在新添加的修改按钮消息响应函数中按如图14-10添加代码:

图14-10

 自此,修改数据库记录功能完成,编译,运行程序,测试该功能。 8.添加删除数据库表记录功能:

 添加删除按钮消息响应函数:具体操作和前面的添加新增或修改按钮的消息响应函

数一样。

 在新添加的删除按钮消息响应函数中按如图14-11添加代码:

72

C++面向对象程序设计实验指导书 实验十四

图14-11

 自此,删除数据库记录功能完成,编译,运行程序,测试该功能。 9.整个工程的功能全部完成,编译运行程序,测试所有程序功能。

14.2.3 实验结果

1.程序的主功能界面如图14-12所示,在该界面上可以通过工具栏中的四个浏览记录按钮浏览数据库中的数据。

四个浏览记录功能按钮

图14-12

2.在主界面上点击[新增]后,将进入新增数据库表记录对话框(如图14-13),在该对话框中输入相关数据后单击[确定],主界面将显示最新增加的记录。

73

C++面向对象程序设计实验指导书 实验十四

图14-13

3.在主界面上点击[修改]按钮后弹出和图14-13类似的对话框,不同的是,通过修改按钮打开来的对话框会把主界面中显示的当前数据显示在对话框的相应控件中,用作修改的依据,点击[确定]后,系统将接受修改后的值,并显示在主界面上。

4.在主界面上点击[删除]记录后,将删除当前显示的记录,并自动将显示的内容后移一条记录。

14.3思考题

1.简述数据库、数据库管理系统、SQL、数据库应用系统之间的关系。

2.针对本实验中完成的程序,说明CDatabase类,CRecordSet类和CRecordView类在本实验中所起的作用。

3.简述本实验程序中连接数据库的过程。 4.改造本实验的程序,使之具有以下功能:

 新增和修改数据库记录对话框中的员工性别只能选取,不能输入;

 新增和修改数据记录时,如果里面的任何一项信息没有输入,则禁止新增和修改,

并提示用户缺乏哪项信息;  新增和修改数据库记录时,员工编号和部门编号只能输入整数,如果输入了非整数

值,则提示用户输入错误,员工薪水只能输入浮点数,如果输入错误则提示用户重新输入。

74

C++面向对象程序设计实验指导书 综合练习

综合练习

本综合练习题中除了需要用到C++课程中学到的理论知识以外,主要还涉及到三大部分的编程技术:Windows多线程编程,Socket网络程序设计和数据库程序设计。同学可以查阅相关的资料来完成下面的练习,练习题的设置如下:

1.高校学生上课签到管理系统的设计与实现。主要用到的技术为数据库程序设计相关技术,主要实现以下功能:

 设计合适的数据库表结构

 记录上课学生迟到,旷课和早退等的次数

 能够统计一定时间内(可以按日期统计,也可以按学期统计)某一学生迟到,旷课

和早退等的次数

 能够统计某一门课不同学生迟到,旷课和早退的次数

 根据不同的扣分权值(如迟到,早退,病假和事假分别每次扣1分,旷课每次扣3

分,但是这个权值可以修改)统计一学期内某一同学某一门课的总扣分值

2.基于TCP/IP的点对点局域网聊天系统的设计与实现。主要用到的技术为Socket网络程序设计,主要实现功能如下:

 本系统分为服务端系统和客户端系统,服务端系统主要功能如下:

 处理用户注册  管理在线用户  处理用户上/下线

 客户端系统主要功能如下:

 注册自己  查找好友  添加好友  在线好友聊天

3.局域网论文管理系统的设计与实现。本系统兼有以上两个系统的功能:即局域网之间用户聊天功能和数据库信息管理功能,但是本系统不分为客户端系统和服务端系统,不同用户之间的协调工作通过动态更新数据表信息来实现,主要实现如下功能:

 本系统中在线的局域网用户之间的聊天功能  用户注册

 论文信息的增加,删除和修改

 论文信息的查找(可以根据不同的关键字来查找)  统计不同的作者在不同时期的论文数

4.局域网问卷调查系统的设计与实现。本系统兼有以上两个系统的功能:即局域网之间用户聊天功能和数据库信息管理功能,但是本系统不分为客户端系统和服务端系统,不同用户之间的协调工作通过动态更新数据表信息来实现,主要实现如下功能:

 本系统中在线的局域网用户之间的聊天功能  用户注册  用户答题

 问卷管理(只有默认的超级用户才有这个功能)  能够分类统计问卷调查的结果

75

C++面向对象程序设计实验指导书 总结

总结

本实验指导书不仅重视理论知识,而且同样重视实践知识,通过先学习理论知识,再在程序中找出理论知识的知识点,最后自己利用这些理论知识的知识点来解决实际问题(哪怕只是实际问题的一小部分)这样的过程来使学生反复地循序渐进地掌握C++程序设计的精华所在。

76

C++面向对象程序设计实验指导书 参考书目

参考书目

《C++面向对象程序设计教程》(第2版) 《面向对象程序设计与Visual C++6.0教程》 《Visual C++面向对象与可视化程序设计》

陈维兴 林小茶编著 陈天华编著 黄维通编著

清华大学出版社

清华大学出版社 清华大学出版社

77

因篇幅问题不能全部显示,请点此查看更多更全内容