《VC++_第1章_Visual_C++程序的建立13958.pdf》由会员分享,可在线阅读,更多相关《VC++_第1章_Visual_C++程序的建立13958.pdf(52页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 1 第 1 章 Visual C+程序的建立 C+面向对象程序设计语言是在 C语言的基础上发展起来的,它与传统的程序设计方式不同,而是一种新的程序设计范型。它对降低软件的复杂性,改善其重要性和维护性,提高软件的生产效率,有着十分重要的意义。因此面向对象程序设计被普遍认为是程序设计方法的一场实质性的革命.Visual C+支持面向对象程序设计,是 Microsoft公司推出的目前应用最为广泛的基于 Windows平台的可视化编程工具。我们将用 Visual C+的强大功能开发 Windows应用程序,设计完成色彩亮丽的可移动的图形图像及千变万化的文字信息和广泛流行的企事业管理、银行、电信、商业
2、、交通、航空航天、教育、游戏等众多的实用软件。1 1 C程序和 C+程序 我们有 C 和 C+编程基础后,才能更好的运用 Visual C+编程工具开发 Windows应用程序。下面我们先用 C语言、C+语言编写一个同样的显示学生信息的程序,熟悉一下它们的编程方法。特别是通过 C+程序设计,进一步掌握面向对象的编程技术,这将对我们学好可视化的 Visual C+程序设计起到促进作用。例 1 用 C 语言编写显示学生信息程序 将 Visual C+6.0软件安装到本机器后,发送到桌面快捷方式。在常用的 e 盘上建一个文件夹名为:vcpp 双击桌面 Visul C+6.0快捷方式FileNewFi
3、leC+source File右边 File处写要建的文件名:学生信息 1 在其下面的 Location即路径名处写:e:vcppok,如图 1.1.1所示,在出现的界面(文档窗口)上可敲入 C 程序,之后单击 BuildBuild是是!(编译运行),便出现图 1.1.2的结果。敲入的 C 程序如下:#include#include struct student /定义 student结构体类型 long num;/学号 char name20;/年龄 char sex10;/性别 float score;/成绩 stu,*p;/直接定义 student结构体类型变量 stu和 student
4、结构体类型指针*p int main()p=&stu;/student结构体的起始地址赋给指针变量 p stu.num=89101;/将学号赋给 stu结构体变量中的成员 num中 strcpy(stu.name,李明);/将姓名赋给 stu结构体变量中的成员 name strcpy(stu.sex,男);/将姓别赋给 stu结构体变量中的成员 sex stu.score=89.5;/将成绩赋给 stu结构体变量中的成员 score /以下 2 个 printf函数输出的结果是相同的。2 printf(学号 No.:%ldn姓名 name:%sn性别 sex:%sn成绩 score:%2.1f
5、n,stu.num,stu.name,stu.sex,stu.score);/stu.num表示 stu结构体变量中的成员 num printf(n学号 No.:%ldn姓名 name:%sn性别 sex:%sn成绩 score:%2.1fn,p-num,p-name,p-sex,p-score);/p-num是代替(*p).num的书写形式,也就是 p-num 等价于(*p).num,它表示 p 指向结构体变/量 stu中的成员 num return 0;图 1.1.1建立 C 语言程序对话框 图 1.1.2 C语言程序运行结果 例 2 用 C+编写显示学生信息程序(1)双击桌面 Visul
6、 C+6.0快捷方式FileNewprojectsWin32 Console ApplicatorProject name处写文件名:学生信息 2,下面 Location处写 e:vcpp okfinishok(2)再在主菜单处点 File NewFile选中 C+Source,右边 Add to Project要置 选中状态,并显示出刚才敲的文件名File处写:学生信息 2.cppok,如图 1.1.3所 示。在出现的窗口界面(文档窗口)上敲入 C+程序。再单击 BuildBuild(编译运行),结果如图 1.1.4所示。敲入的 C+程序如下:#include#include /类的说明部分
7、 class student /定义类(class)student private:/私有部分 public:/公共部分 long num;/学号 char name20;/姓名 char sex10;/性别 float score;/成绩 void sc();/输出函数 protected:/保护部分 3;/类的实现部分 void student:sc()/在 student类里面定义的函数 sc()的具体实现 student stu;student*p=&stu;stu.num=89101;strcpy(stu.name,李明);strcpy(stu.sex,男);stu.score=89
8、.5;/以下 2 种输出结果都是相同的 cout学号 No:stu.numn;cout姓名 name:stu.namen;cout性别 sex:stu.sexn;cout成绩 score:stu.scorenn;cout学号 No:numn;cout姓名 name:namen;cout性别 sex:sexn;cout成绩 score:scorenn;/主函数体 void main()/主函数,程序从这里开始执行 student xx;/定义 student类的对象 xx xx.sc();/sc()是 xx(student)的成员函数,xx.sc()是表示访问 xx 的成员函数 sc()图 1.
9、1.3建立 C+程序对话框 图 1.1.4 C+程序运行结果 我们看到,C 语言是先定义结构体和结构体变量、结构体指针,之后在主函数 main()里用结构体变量和结构体指针输出其变量内容。C+是先定义类,在主函数里用类定义对象,再通过对象里的成员函数输出其变量内容。C 和 C+的最大区别是 C+定义的类里可以有成员函数,通过成员函数完成所要完成的工作,在程序结构上有了深刻变化,是面向对象的。而 C 的结构体里不能定义函数,它不具备类的功能,程序是结构化的、面 4 向过程的。1 2 面向对象的编程技术 面向对象包括面向对象分析和面向对象程序设计。面向对象程序设计技术的提出,主要是为了解决传统的结
10、构化程序设计所不能解决的代码重用问题。1 2 1 类与对象 我们在例 2程序中已经定义了类:student和其对象:xx。“类”就是对具有相同数据和相同操作的一组相似对象的定义,即类是对具有相同特征和行为的一个或多个对象的描述。在面向对象程序设计中,“类”是一个最重要的概念。类的结构(也即类的组成,如例 2 中的:学号num、姓名name、性别 sex、成绩 score、输出函数 sc())是用来确定一类对象的行为的,而这些行为是通过类的内部数据结构和相关操作来确定的。类通过其成员函数(如例 2 中的:sc())来描述这些行为,而成员函数又被称为类的对象向其他对象所提供的服务。与类对应的就是对
11、象了。对象就是由某个特定的类所描述的一个具体的实例。例如,“车”是一个类,一种具体的车如“货运车”就是一个具体的对象了。对象是类的实例,类是具有公共特性的对象的抽象。对象的定义:一个类定义后,就可以定义该类的对象,如:例 2 中的:student xx;其定义的格式为:;其中,类名是用户定义过的类的标识符,对象名可以有一个或多个,多个时要用逗号分隔。被定义的对象即可以是一个普通对象,也可以是一个数组对象或指针对象。如:CMeter myMeter,*Meter,Meters5;这时,myMeter是类 CMeter的一个普通对象,Meter和 Meters分别是类的一个指针对象和对象数组。一个
12、对象的成员就是该对象的类所定义的数据成员(成员变量)和成员函数。访问对象的成员变量、成员函数和访问变量和函数的方法是一样的,只不过要在成员面前加上对象名和成员运算符”.”,例如:例 2 中的:xx.sc()。具体表示方式如下:.()例如:myMeter.m_nPercent,myMeter.SetPos(5),Meters0.StepIt();需要说明的是,一个类对象只能访问该类的公有型成员,而对于私有型成员则不能访问。上述成员 m_nPercent、SetPos()、StepIt()都是 public(公有)访问类型。若对象是一个指针,则对象的成员访问形式如下:-()例如(见例 4 所示):
13、Date*datel;/定义 Date 类的指针对象 datel=new Date(1998,4,28);/Date()是类 Date 中定义的构造函数,这里是执行构造函数,并为类/Date 开辟一片内存单元,且将这片内存单元的首地址赋给指针变量 datel。datel-showDate();/访问 Date 类的成员函数。5“-”是一个表示成员的运算符,它与“.”运算符的区别是:“-”用于表示指向对象的指针的成员,而“.”用于表示一般对象的成员。1 2 2 类及其成员变量与成员函数的声明和定义 类的定义格式一般可分为说明部分和实现部分。说明部分用来说明该类中的成员,包含数据成员的说明和成员函
14、数的说明。成员函数是用来对数据成员进行操作的,又称为“方法”。实现部分是对成员函数的定义。概括说来,说明部分是告诉使用者“做什么”,而实现部分则告诉使用者“怎么做”。类的一般定义格式如下:class public:公有数据成员的说明;公有成员函数的说明;protected:保护数据成员的说明;保护成员函数的说明;private:私有数据成员的说明;私有成员函数的说明;class是定义类的关键字,是用户定义的类的名字,通常用大写的 C 字母开始的标示符作为类名。花括号 内是类的说明部分,说明该类的成员。类的成员包含数据成员和成员函数两部分。public 称为类的公有部分,这部分的数据成员和成员函
15、数可由程序中的函数(包括类内和类外)访问,即它对外是完全开放的。private 称为类的私有部分,这一部分的数据成员和成员函数只能由本类的成员函数访问,而类外部的任何访问都是非法的。实现了访问权限的有效控制。protected 称为类的保护部分,这部分的数据成员和成员函数可以由本类的成员函数访问,也可以由本类的派生类的成员函数访问,而类外的任何访问都是非法的。即它是半隐蔽的。关键字 public、private和 protected被称为访问权限修饰符或访问控制修饰符。它们在类体内(即花括号 内)出现的先后顺序不限,并且允许多次出现,可用它们来说明类成员的访问权限。是类定义中的实现部分,这部分
16、包含所有在类体内说明的函数的定义,如例 2 中的:void student:sc();如果一个成员函数在类体内定义了,则实现部分将不再出现。如果所有的成员函数都在类体内定义,则实现部分可以省略。需要说明的是,当类的成员函数的函数体在类的外部定义时,必须由作用域运算符”:”来通知编译系统该函数所属的的类。为了进一步明确类的定义,除了例 2 外,我们再给出一个日期类定义的例子。例 3 定义日期类#include 6/类的说明部分 class Date public:/公有部分 void SetDate(int y,int m,int d);/说明为 year、month、day设置初值的函数 in
17、t IsLeapYear();/说明判别是否是闰年函数 void Print();/说明输出函数 private:/私有部分 int year,month,day;/说明用来表示年、月、日的整型变量;/类的实现部分 void Date:SetDate(int y,int m,int d)/为 year、month、day设置初值函数的实现 year=y;/年 month=m;/月 day=d;/日 /判别是否是闰年函数的实现,能被 4 整除与不能被 100整除或能被 400整除 int Date:IsLeapYear()return(year%4=0)&(year%100)!=0)|(year
18、%400=0);void Date:Print()/输出函数的实现 coutyear.month.dayendl;/输出年、月、日/主函数体 void main()Date da;/定义 Date类对象 da da.SetDate(2000,6,28);/执行类 Date的函数 SetDate(2000,6,28),参数为年、月、日 da.IsLeapYear();/执行类 Date的函数IsLeapYear()da.Print();/执行类 Print()函数 说 明:1、程序中出现的”:”是用来标示某个成员函数是属于哪个类的。该类还可以如下定义:class Date public:void
19、 SetDate(int y,int m,int d)year=y;month=m;day=d;int IsLeapYear()return(year%4=0)&(year%100)!=0)|(year%400=0);void Print()/输出函数体 coutyear.month.dayendl;private:int year,month,day;7 可以看出,程序中对成员函数的实现(即函数的定义)都写在了类体内,因此类的实现部分被省略了。2、在类体中不允许对所定义的数据成员进行初始化。3、类中的数据成员的类型可以是任意的,包括整型、浮点型、字符型、数组、指针、引用、无类型(void)以
20、及对象等。4、经常习惯地将类定义的说明部分或者整个定义部分(包含实现部分)放在一个头文件中。5、程序中的 cout叫输出流,它可以是一个整数、实数、字符及字符串,cout中的插入符”可以连续写多个,每个后面跟一个表达式,该表达式通常是获得输入值的变量或对象。若程序中有如下语句:int nNum1,nNum2,nNum3;cinnNum1nNum2nNum3;这两条语句是定义 3 个整型变量,并要求用户从键盘上输入 3 个数。输入时,必须在 3 个数值之间加上一些空格来分隔,空格的个数不限,最后按回车结束输入。1 2 3 构造函数和析构函数 构造函数和析构函数是在类体中说明的两种特殊的成员函数。
21、构造函数的功能是在创建对象时,使用给定的值将对象初始化;析构函数与构造函数正好相反,其功能是释放一个对象,在删除对象前,用它来做一些内存释放等清理工作。1、构造函数 由于在类的定义中不能对数据成员进行初始化,为了能给数据成员自动设置某些初 始值,需要使用构造函数。构造函数具有以下特征:(1)构造函数的名字与类名相同,否则编译程序将把它当作一般的成员函数来处理。(2)构造函数没有返回值。(3)构造函数的功能是对对象进行初始化,且一般只对数据成员进行初始化。在构造函数中一般不做赋初值以外的事情。(4)构造函数不能像其他成员函数那样被显示地调用,它是在对象创建时被调用的。(5)在一个类中可以定义多个
22、构造函数。例 4 定义构造函数#include class Date public:Date(int y,int m,int d);/构造函数 void setDate(int y,int m,int d);/一般的成员函数,设置日期函数 void showDate();/一般的成员函数,显示日期函数 private:int year;/私有成员变量,年 int month;/私有成员变量,月 int day;/私有成员变量,日;8 Date:Date(int y,int m,int d)/构造函数的实现 coutConstructing Function endl;year=y;/为 yea
23、r 赋值 month=m;/为 month 赋值 day=d;/为 day 赋值 void Date:setDate(int y,int m,int d)/一般成员函数,设置日期函数的实现 year=y;/为 year 赋值 month=m;/为 month 赋值 day=d;/为 day 赋值 inline void Date:showDate()/一般成员函数,显示日期函数的实现 coutyear.month.dayendl;/输出年、月、日 void main()Date*datel;/定义指针对象 Datel datel=new Date(1998,4,28);/构造函数,为 year
24、、month、day 赋初值 /以上两条语句可合成写:Date*datel=new Date(1998,4,28);coutDatel output1:showDate();/访问显示成员函数,显示构造函数所赋的年、月、日值 datel-setDate(2008,10,22);/访问设置日期函数,参数是年、月、日 coutDatel output2:showDate();/访问显示成员函数,显示 setDate()函数所赋的年、月、日值 delete datel;/释放datel所占用的内存空间 2、析构函数 与构造函数相对应的是析构函数。析构函数是另一个特殊的 C+成员函数,它只是在类名称前
25、面加上一个”符号。每一个类只有一个析构函数,没有任何参数,也不返回任何值。例如:class CMeter public:CMeter()/析构函数 析构函数只有在下列两种情况下才会被自动调用:(1)当对象定义在一个函数体中,该函数调用结束后,析构函数被自动调用。(2)用 new为对象分配动态内存,当使用 delete释放对象时,析构函数被自动调用。3、默认构造函数和析构函数 在类定义时,如果没有定义任何构造函数,则编译器自动生成一个不带参数的默认构造函数。同样,如果一个类中没有定义析构函数时,则编译系统也生成一个称为默认析构函数。例如,前面定义的 CMeter类来说,当没有定义任何构造函数和析
26、构函数时,9 系统自动生成的默认构造函数和析构函数如下所示:CMeter()/默认构造函数的形式 CMeter()/默认析构函数的形式 需要说明的是,在用户定义一个对象时,编译器会自动根据对象定义的格式选择相应的构造函数。例如:CMeter m1,m2;由于 m1 和 m2 不带任何参数,当类没有用户定义的构造函数时,则编译器会使用默认构造函数对 m1 和 m2 进行初始化。用默认构造函数对对象进行初始化,则将对象的所有数据成员都初始化为零或空。1 2 4 类的继承 继承是面向对象程序设计的一个重要特性,它允许在已有类的基础上创建新的类,新类可以从一个或多个已有类中继承成员函数和数据成员,而且
27、可以重新定义或加进新的数据和函数,从而形成类的层次或等级。其中已有类称为基类或父类,在它基础上建立的新类称为派生类、导出类、子类。1、继承与派生类(1)为什么要使用派生类 例如有类:class CPerson private:public:CPerson();/构造函数 protected:char name10;/姓名 char sex4;/性别;再如我们又要声明一个类 employee 类,它也包含有 char name10(姓名)、char sex(性别)。还包含 char department(部门)、float salary(工资)等数据成员和显示函数 show()。class CE
28、mployee private:public:void show();/显示函数 protected:char name10;/姓名 这条重复 char sex4;/性别 这条重复 char department20;/部门 char pos10;/职务;两个类中的代码象这样重复的现象,必须引入继承,将 CEmployee 类说明成 CPerson类的派生类,那些相同的成员在 CEmployee 类中就不需要再说明了。10 2、派生类的声明 将上面的 CPerson类定义好后,再定义其派生类 CEmployee 如:class CEmployee:public CPerson/CEmploye
29、e 是派生类,public 表示公共继承,CPerson 是基类 private:public:void show();/显示函数 和 CPerson 类不重复的语句 protected:char department20;/部门 和 CPerson 类不重复的语句 char pos10;/职务 和 CPerson 类不重复的语句 这样 CEmployee 类即具有了 CPerson类的功能(姓名、性别),又增加了具有“部门”、“职务”和”显示函数”的功能。下面是声明一个派生类的格式:class 派生类名:继承方式 基类名 派生类新增的数据成员和成员函数;继承方式:(1)公有继承 class
30、employee:public person ;(2)私有继承 class employee:private person ;(3)保护继承 class employee:protected person ;类的继承方式指定了派生类成员以及类外对象对于从基类继承来的成员的访问权限。从已有类派生出新类时,可以在派生类内完成以下几种功能:(1)可以增加新的数据成员和成员函数(2)可以重新定义基类中已有的成员函数(3)可以改变现有成员的属性 例 5 派生类的公有继承示例#include#include class CPerson private:public:CPerson();/构造函数 prot
31、ected:char name10;/姓名 char sex4;/性别;/构造函数的实现,在主函数中定义对象时,该函数自动执行,为 name 和 sex 赋值 11 CPerson:CPerson()strcpy(name,李明);/为 name 赋值 strcpy(sex,男);/为 sex 赋值 /CEmployee 类继承了 CPerson 类的所有功能,同时还增加了”部门”、”职务”和”输出函数”的功能/CEmployee 是派生类,public 表示公有部分,CPerson 是基类,该派生类中还具有了 name 和 sex class CEmployee:public CPerson
32、 private:public:void show();/输出函数 和 CPerson 类不重复的语句 protected:char department20;/部门 和 CPerson 类不重复的语句 char pos10;/职务 和 CPerson 类不重复的语句;void CEmployee:show()/派生类 CEmployee 的输出函数的实现 CEmployee cem;/定义派生类 CEmployee 的对象 cem CEmployee*p=&cem;/对象的首地址赋给 CEmployee 类型的指针变量 p cout姓名:nameendl;/输出姓名 cout性别:sexen
33、dl;/输出性别 strcpy(cem.department,软件开发部);/为”部门”赋值 cout部门:departmentendl;/输出部门的名字:软件开发部 strcpy(cem.pos,经理);/为”职务”赋值 cout职务:posx;此时用户从键盘输入的数值会自动地转换为变量 x 的类型,并存入变量 x内。x必须是基本数据类型,但不能是 void类型。它还允许一连串的输入数据,如:cinabc;按书写顺序从键盘上提取所要求的数据,并存入对应的变量中。两个数据间用空格分隔。couty;变量y 的值将显示在屏幕上。y 必须是基本数据类型,但不能是void类型。运算符”允许用户连续输出
34、一连串数据,也可以输出表达式的值。如:couta+bc;按书写顺序将数据输出到屏幕上。注意,使用 cin和 cout进行 I/O操作时,在程序中必须嵌入头文件 iostream.h系统文件,否则编译时会产生错误。例 6 C+输入输出实例#include int main()char name20;coutname;/在终端上输入姓名后,存入到变量 name中 coutnameendl;/在终端上输出姓名 return;说 明:程序中,endl(或用 n)是表示结束并换行。2、&和*运算符 C+中有 2 个专门用于指针的运算符:&(取地址运算符)、*(取值运算符),运算符”&”只能对变量操作,作
35、用是取该变量的地址。运算符”*”用于取指针或地址所指内存单元中存储的内容。例如:int a=3;/整型变量 int*p=&a;/指向整型变量的指针,其值等于 a 的地址 int b=*p;/将指针所指的地址中的内容赋值给 b,值为 3 int*pi;/指向整型变量的指针 pi=p;/将指针 p 的地址赋给指针 pi,使得它们都是指向 a 的指针 例 7 应用&和*运算符的实例#include void main()int*p1,*p2,*p,a,b;coutab;/在终端上输入 a 和 b 两个数,输入时这两个数用空格分开 p1=&a;/存放 a 值的地址赋给指针变量 p1 p2=&b;/存放
36、 b 值的地址赋给指针变量 p2 if(ab)/如果 a 小于 b,则存放 a 值的地址和存放 b 值的地址进行交换,保证 p1 的内容值最大 13 p=p1;p1=p2;p2=p;couta=a,b=bendl;cout最大的值是:*p1,最小的值是:*p2n;3、this 指针 当定义了一个类的若干对象后,每个对象都有属于自己的数据成员,但是所有对象的成员函数代码却合用一份。那么成员函数是怎样辨别出当前调用自己的是哪个对象,从而对该对象的数据成员而不是对其它对象的数据成员进行处理呢?看下面的例子:例 8 this 指针的引用#include class CStudent public:CS
37、tudent(int zx)x=zx;void disp()cout x=xendl;private:int x;main()CStudent sa(1),sb(2);cout sa:;sa.disp();cout sb:;sb.disp();return 0;这里 sa.disp 和 sb.disp 之所以能够按自己的意愿调用函数 disp()函数,而输出不乱,是因为 C+为成员函数提供了一个名为 this 的指针,这个指针称为自引用指针。每当创建一个对象时,系统就把 this 指针初始化为指向该对象。每当调用一个成员函数时,系统就自动把 this 指针作为一个隐含的参数传给该函数。不同的对
38、象调用同一个成员函数时,C+编译器将根据成员函数的 this 指针所指向的对象来确定应该引用哪一个对象的数据成员。因此,被存取的必然是指定对象的数据成员,绝不会搞错。一般,this 指针在系统中是隐含存在的,也可显式地表示出来。例如上例:cout“x=”xendl 和 cout“x=”xendl;是等价的 4、const 修饰符 14 const 是用来定义常量的修饰符,如:const float PI=3.14;这个常量是类型化的,它有地址,可以用指针指向这个值,但不能修改它。在 C 语言中,习惯用#define PI 3.14;来定义常量 PI;#define 与 const 的作用相似,
39、但 const 的安全性好,因此 C+中用 const 代替#define。例 9 用 const 取代#define#include int main()int a=1;/#define t1 a+a /#define t2 t1%t1 const t1=a+a;/定义常量 t1,t1 的值是 a+a const t2=t1%t1;/定义常量 t2,t2 的值是 t1%t2 cout t2 is t2 endl;/输出 t2 return;输出结果:t2 is 0 但是如果用被注释的两条语句:#define t1 a+a 和#define t2 t1%t1 代替 const t1=a+a和c
40、onst t1%t1 两条语句则得出错误结果是:t2 is 2,原因是C+把cout t2 is t2 endl;语句译成了:cout “t2 is”a+a%a+a endl;(1+0+1=2)。5、void型指针 void 通常表示无值,但将 void 作为指针类型时,它却表示不确定的类型。这种 void 型指针是一种通用型指针,也就是说任何类型的指针值都可以赋给 void 类型的指针变 量,例如:void pa;/错误,不能声明 void 类型的变量 void *pc /正确,可以声明 void 类型的指针 需要说明的是,这里说 void 型指针是通用型指针,是指它可以接受任何类型的指针的
41、 赋值,但对已获值的 void 型指针,对它再进行处理,如输出或传递指针时,则必须再进 行显示类型转换,否则会出错误。例如:例 10 void 型指针的使用#include main()void*pc;/声明 void(无类型或叫通用性)指针 pc int i=123;char c=a;pc=&i;/将存放整型数 123 的变量 i 的地址赋给 void 型指针 pc cout *(int*)pc endl;/输出指针值 123,要进行整型数类型转换 pc=&c;/将存放字符 a 的变量 c 的地址赋给 void 型指针 pc cout *(char*)pc endl;/输出指针值 a,要进行
42、字符型数类型转换 15 return 0;输出结果:123 a 6、new和 delete 程序运行时,计算机的内存被分成 4 个区:程序代码区、全程数据区、栈(后进先出区)和堆,其中堆可由用户分配和释放。C 语言中使用函数 malloc()和 free()来进行动态内存管理(分配与释放)。而 C+则提供了操作符 new 和 delete 来做同样的工作,其性能比 malloc()和 free()更优越,使用更方便灵活。运算符 new 用于内存分配的最基本的语法形式为:指针变量=new 类型名;该语句在程序运行过程中从称为堆栈的一块自由存储区中为程序分配一块sizeof(类型名)字节大小的内存
43、空间,该内存空间的首地址被存于指针变量中。运算符 delete 用于释放分配的存储空间,其基本形式为:detele 指针变量;期中,指针变量保存着new分配的内存的首地址。new和delete操作的简单例子如下:例 11 操作符 new 和 delete 的使用#include main()int*p;/声明一个整型指针变量 p p=new int;/动态分配一个存放 int 整型数据的内存空间,并将首地址赋给 p *p=10;/将整型数 10 送到 new 分配的内存空间 cout *pendl;/输出这个整型数 10 delete p;/释放 new 分配的内存空间 return 0;7、
44、作用域标示符:通常情况下,如果有两个同名变量,一个是全局的,另一个是局部的,那么局部变量在其作用域内具有较高的优先权。如果希望在局部变量的作用域内使用同名的全局变量,可以在该变量前面加上“:”,如:avar代表全局变量 avar,“:”称为作用域标示符。例如:例 12 使用作用域标示符#include int avar;/全局变量 main()int avar;/局部变量 avar=25;/25赋给局部变量 avar:avar=10;/10赋给全局变量 avar cout“local avar=”avarendl;/输出局部变量 avar的值是 25 16 cout“global avar=”
45、:avarTextOut(20,20,学号 num:);pDC-TextOut(110,20,num);pDC-TextOut(20,40,姓名 name:);pDC-TextOut(110,40,name);/输出姓名 pDC-TextOut(20,60,性别 sex:);pDC-TextOut(110,60,sex);/输出性别 pDC-TextOut(20,80,成绩 score:);pDC-TextOut(110,80,score);/输出成绩 (4)单击菜单中的 BuildBuild(编译运行),便在窗口上显示出图 1.3.2的学生信息。说 明:1、OnDraw(CDC*pDC)函数
46、是视图类中的显示函数(函数也叫对象方法)。2、CDC类:是 FMC的设备环境类,CDC*pDC是定义 CDC类的指针对象*pDC。3、CMyDoc*pDoc:是定义文档类的指针对象*pDoc。4、GetDocument()函数是获得文档类指针。5、CMyDoc*pDoc=GetDocument():是将文档类首地址赋给文档类指针*pDoc。6、ASSERT_VALID(pDoc):该宏用来在运行时检查一个对象的内部合法性,这里是测试获得的文档类指针。7、CString:是处理文本串的类,它能将字符串处理为字符数组。8、TextOut(x,y,str):是 CDC类的显示函数,参数 x,y是字符
47、串在窗口中的显示位置(x y 坐标),str是以上已定义和赋好值的字符串。Visual C+编程方式与 C 和 C+又有了很大 不同,我们看到程序建立后,系统自动生成一些 类,这些类以文件的形式存在。如:视图类(学 生信息 3View.h、学生信息 3View.cpp)、文档类(学 生信息 3Doc.h、学生信息 3Doc.cpp)、主框架类(Mainfrm.h、Mainfrm.cpp)、应用程序类(学生信 息 3.h、学生信息 3.cpp)等 4 个主要的类(见附页)。以后所有的单文档项目都要用到这 4 个主要的类,图 1.3.2 Visual C+运行结果 通过添加代码等,来完成所要完成的
48、工作。1 4 使用 MFC AppWizard应用程序向导 在上节中,我们已经用 MFC AppWizard建立了一个学生信息 3的应用程序,程序建立后,系统自动为其生成了一些类文件,有了这些文件,我们可以不加任何代码,就能运行程序;结果是在屏幕上显示一个空白窗口。我们将在这个空白窗口上完成任何工作(上例就是在这个空白窗口上显示学生信息的)。Visual C+6.0中的 MFC AppWizard能为我们快速、高效、自动地生成一些常用的标准程序结构和编程风格,它们被称为应用程序框架结构。1 4 1 应用程序框架类型 在用 MFC Windows建立一个单文档应用程序时,我们在开始的“New”对
49、话框中就要 18 选择最常用的 MFC AppWizard(exe)应用程序框架类型。该类型是用于创建可执行的WinDows应用程序,它包含用户最常用、最基本的以下 3 种应用程序类型:1、单文档应用程序:它的功能比较简单,复杂程度适中,虽然每次只能打开和处理一个文档,但已能满足一般工程上的需要。2、多文档应用程序:能允许同时打开和处理多个文档。与单文档应用程序相比,增加了许多功能,需要大量额外的编程工作。例如它不仅需要跟踪所有打开文档的路径,而且还需要管理各文档窗口的显示和更新等。3、基于对话框的应用程序:对比单文档更简单,也是最紧凑的。它没有菜单、工具栏及状态栏,也不能处理文档,但它的好处
50、是速度快,代码少,程序员所花费的开发和调试的时间短。总之,无论你选择何种类型的应用程序框架,一定要根据自己的具体需要而定。表1.1列出了在 Visual C+6.0中,MFC AppWizard创建的应用程序框架类型。这些类型基本上满足了各个层次用户的需要。1 4 2 用 MFC AppWizard(exe)创建一个单文档的应用程序 例 14 创建一个“显示两行字”的单文档应用程序 1、双击桌面上的 Visual C+6.0快捷方式 选择“File”“New”菜单,在弹出的“New”对话框中,可以看到工程标签页面中显示出一系列的应用程序项目类型,表 1.1列出了所有应用程序项目类型;选择 MF