工程化程序设计(VCNET)第2章C语言基础_第1页
工程化程序设计(VCNET)第2章C语言基础_第2页
工程化程序设计(VCNET)第2章C语言基础_第3页
工程化程序设计(VCNET)第2章C语言基础_第4页
工程化程序设计(VCNET)第2章C语言基础_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

工程化程序设计〔VisualC++.NET〕第2章C++语言根底课程描述:C++提出了把数据和在数据之上的操作封装在一起的类、对象和方法的机制,并通过派生、继承、重载和多态性等特征,实现了人们期待已久的软件重用和程序自动生成,从而大大提高了软件的开发效率和质量。VisualC++并非代表一种新的语言,而是一种C++的编程方式。因此,掌握C++是学习VisualC++的前提。第2章C++语言根底

了解C++程序结构

掌握引用的有关内容。

熟练操作运用3种不同方式传递函数参数。理解类与对象的概念及特性。熟练声明一个类和对象的方法。知识点及技能点知识点及技能点熟练掌握类的构造函数和析构函数。掌握类的静态数据成员和成员函数、友元函数。理解类的继承和派生。理解重载函数和重载运算符、多态性。熟练操作虚函数。主要内容2.1创立Win32控制台应用程序2.2C++概述2.3引用2.4函数的参数传递2.5new与delete2.6类与对象2.7类的继承2.8重载2.9多态性重点和难点讨论本章小结作业及练习所谓控制台应用程序是指那些需要与传统DOS操作系统保持某种程度的兼容,同时又不需要为用户提供完善界面的程序;简单地讲,就是指在Windows环境下运行的DOS程序。2.1创立Win32控制台应用程序案例:创立一个简单的Win32应用程序目标:通过创立一个Win32应用程序框架,了解如何在集成开发环境下建立C++语言编程环境。任务:使用VisualC++.NET工具,创立一个Win32控制台应用工程,要求在屏幕上显示“HelloWorld!〞字样。案例分析案例分析图2-1创立Win32控制台应用程序步骤:1〕创立一个空的工程。在图2-1中选择“Win32工程〞,工程名称可以用Win32App。然后单击“确定〞按钮,就会出现图2-2。图2-2应用程序向导的默认状态案例分析选择“应用程序设置〞选项,进入如图2-3所示的界面。选择“控制台应用程序〞单项选择按钮,并选中“空工程〞复选框。图2-3“应用程序设置〞选项卡案例分析2〕编写代码假设要在显示器上显示“HelloWorld!〞,首先要创立一个能编写代码的文件。请选择集成开发环境的“工程〞→“添加新项〞命令,翻开“添加新项〞对话框如图2-4所示。选择“C++文件(.cpp)〞选项,然后将其命名为Win32App,与工程名称相同。图2-4添加文件工程案例分析单击图2-4中的“翻开〞按钮,在集成开发环境中可以看到一个翻开的空白的文件〔Win32APP.cpp〕,然后开始向这个文件中添加显示“HelloWorld!〞的代码。#include<iostream.h>voidmain(){//输出一行文本cout<<"HelloWorld!"<<endl;}案例分析3〕编译运行。写完代码后就可以编译运行了。结果如图2-5所示。

图2-5Win32App运行结果至此,已经完成了简单Win32控制台应用程序的创立,读者不难发现,同MFC应用程序相比,控制台应用程序的运行结果显示在DOS环境下。案例分析1.C++程序结构下面是一个简单的C++程序://这是一个简单的C++程序#include<iostream.h>voidmain(void){inti;cout<<〞欢送使用?工程化程序设计---VisualC++.NET教程?!\n〞;cout<<〞请输入要返回的值:\n〞;cin>>i;}分析2.2C++概述1〕第1条语句是C++语言的注释语句。其中,“//〞是C++语言的注释符号,表示以“//〞开始的一行语句为注释行。2〕第2条语句用于将定义输入/输出函数〔cin、cout〕的头文件iostream.h包含到程序中。3〕第3条语句说明主程序的开始,表示主程序返回的是void类型的数据,其传递值也是void类型。4〕第5条语句声明了一个整型变量i。2.2C++概述5〕第6条和第7条语句是C++语言的输出语句,可以将指定的字符串输出到屏幕上。cout函数在头文件iostream.h中定义。6〕第8条语句是C++语言的输入语句,表示向变量i中输入一个值。cin函数也是在头文件iostream.h中定义的从以上例子中可以看出,一个C++程序往往是由预处理命令、函数、语句、变量和对象、输入与输出以及注释等几个根本局部组成的。2.2C++概述表2-1C++运算符参见主教材表2-1。1、引用的概念。2、引用的操作。2.3引用引用是个别名,当建立引用时,程序用另一个变量或对象〔目标〕的名字初始化它。从那时起,引用作为目标的别名而使用,对引用的改动实际就是对目标的改动。为建立引用,先写上目标的类型,后跟引用运算符“&〞,然后是引用的名字。引用能使用任何合法变量名。例如,引用一个整型变量:intsomeInt;int&rInt=someInt;声明rInt是对整数的引用,初始化为引用someInt。在此,要求someInt已经有声明或定义,而引用仅仅是它的别名。引用的概念例2-1下面的程序建立和使用引用#include<iostream.h>voidmain(){intintOne;int&rInt=intOne;intOne=5;cout<<“intOne:〞<<intOne<<endl;cout<<“rInt:〞<<rInt<<endl;rInt=7;cout<<“intOne:〞<<intOne<<endl;cout<<“rInt:〞<<rInt<<endl;}程序的运行结果如下:intOne:5rInt:5intOne:7rInt:7引用的概念如果程序寻找引用的地址,它只能找到所引用的目标的地址。例2-2下面的程序取引用的地址。#include<iostream.h>voidmain(){intintOne;int&rInt=intOne;intOne=5;cout<<“intOne:〞<<intOne<<endl;cout<<“rInt:〞<<rInt<<endl;cout<<“&intOne:〞<<&intOne<<endl;cout<<“&rInt:〞<<&rInt<<endl;}程序的运行结果如下:intOne:5rInt:5&intOne:00F3:5300&rInt:00F3:5300引用的操作1.按值传递所谓按值传递,是指当一个函数被调用时,C++根据实际和形式参数的对应关系将实际参数的值一一传递给形式参数,供函数执行时使用。函数本身不对实际参数进行操作,也就是说,即使形式参数的值在函数中发生了变化,实际参数的值不会受到影响。2.地址传递所谓地址传递,是指在函数定义时,将形式参数声明成指针,这样调用函数时就需要指定地址值形式的参数。3.引用传递

传递引用给函数与传递指针的效果一样,传递的是原来的变量或对象,而不是在函数作用域内建立变量或对象的副本。2.4函数的参数传递例题分析例2-3按值传递例2-4地址传递例2-5引用传递请看例题2.4函数的参数传递例2-3下面是想通过swap()函数调用来交换两个整数值的程序#include<iostream.h>voidswap(int,int);voidmain(){inta=3,b=8;cout<<“a=〞<<a<<“,b=〞<<b<<endl;swap(a,b);cout<<“afterswapping…\n〞;cout<<“a=〞<<a<<“,b=〞<<b<<endl;}voidswap(intx,inty){inttemp=x;//交换两个形参x=y;y=temp;}程序的运行结果如下:a=3,b=8afterswapping…a=3,b=8按值传递例2-4下面的程序通过传递指针来实现整数值的交换#include<iostream.h>voidswap(int*,int*);voidmain(){inta=3,b=8;cout<<“a=〞<<a<<“,b=〞<<b<<endl;swap(&a,&b);cout<<“afterswapping…\n〞;cout<<“a=〞<<a<<“,b=〞<<b<<endl;}voidswap(int*x,int*y){inttemp=*x;//交换两个形参*x=*y;*y=temp;}运行结果为:a=3,b=8afterswapping…

a=8,b=3地址传递例2-5下面的程序用引用改写swap()函数的定义及调用#include<iostream.h>voidswap(int&rx,int&ry);voidmain(){intx=5;inty=6;cout<<“beforeswap,x:〞<<x<<“,y:〞<<y<<endl;swap(x,y);cout<<“afterswap,x:〞<<x<<“,y:〞<<y<<endl;}voidswap(int&rx,int&ry){inttemp;temp=rx;rx=ry;ry=temp;}运行结果为:beforeswap,x:5,y:6afterswap,x:6,y:5引用传递在C++中,用new与delete进行动态内存的分配与释放。运算符new返回指定类型的一个指针,如果分配失败(如没有足够的内存空间)时那么返回0。例如:double*p;p=newdouble;系统自动根据double类型的空间大小开辟一个内存单元,并将地址放在指针p中。运算符delete操作是释放new请求到的内存。例如:deletep;2.5new与delete面向过程编程与面向对象编程比较。定义类。定义对象。构造函数与析构函数。对象与成员函数。2.6类与对象面向对象程序设计方法的主要思想是将数据(数据成员)及处理这些数据的相应函数(成员函数)封装到类中,而使用类的变量那么称为对象。在对象内,只有属于该对象的成员函数才可以存取该对象的数据成员。这样,其他函数就不会无意中破坏其内容,从而到达保护和隐藏数据的效果。面向过程编程与面向对象编程比较类是一种用户自定义的数据类型。声明一个类时,以关键字class开始,然后是类的名字。其语法结构如下:class<类名称>{private:[<私有数据和函数>]public:[<公有数据和函数>]};定义类例2-6以下是应用类的简单例子#include<iostream.h>#include<math.h>classcounter{ doubledata_value;//声明一个私有类型数据public: voidset_value(double);//声明一个公有类型的成员函数 doubleget_value(void);//声明一个公有类型的成员函数 intget_num(void);//声明一个公有类型的成员函数}sam;//声明类对象sam例题分析voidcounter::set_value(doublev)//成员函数的定义{ data_value=v;}doublecounter::get_value(void)//成员函数的定义{ doubledd; dd=sin(10.0*data_value); return(dd);}intcounter::get_num(void)//成员函数的定义{ intii; ii=int(data_value); return(ii);}main(){sam.set_value(50.0);//设置初值cout<<"Thevalueis“<<sam.get_value()<<endl;cout<<"Thenumis“<<sam.get_num()<<endl;return(0);}例题分析

提示:与结构一样,类也是一种数据类型。要想使用类,还必须声明对象(object)。对象是类的实例,在前面的例子中,实际上已涉及到了对象的声明,即在声明类时直接定义对象。此外,还可以在声明类之后再单独声明类对象。请看下面例子:例如:classexample//声明类example{inti;public:floatf;voidfun();};exampleA;//声明类对象A定义对象

提示:1)对象声明后即可使用,使用方法是:对象名.成员函数名或对象名.数据成员名例如,可以按以下方式调用类example中的成员函数fun()

A.fun();2)在本例中,对象A所能使用的数据和函数只有变量f和成员函数fun。变量i为类example的私有数据,不能通过A.i使用,如何访问i,请思考。定义对象C++的构造函数和析构函数,使类对象能够轻松地被创立和撤销。构造函数创立类对象,初始化其成员,析构函数撤销类对象。构造函数和析构函数都是类的特殊成员函数。构造函数与析构函数构造函数与析构函数提示:1〕构造函数是与类同名的类的特殊成员函数,在该类的对象创立时,自动被调用。构造函数也可以在类的外部定义,方法同普通的类的成员函数。2〕构造函数没有返回类型,函数体中也不允许返回值,但可以有无值返回语句“return;〞。因为构造函数专门用于创立对象和为其初始化,所以它不能随意被调用。3〕如果一个类对象是另一个类的数据成员,那么在那个类的对象创立所调用的构造函数中,对该成员(对象)自动调用其构造函数。例2-7下面的程序,一个“帮教派对〞类TutorPair中,包含有学生类对象和老师类对象#include<iostream.h>classStudent{public:Student(){cout<<“constructingstudent.\n〞;someHours=100;gpa=3.5;}/*~Student(){cout<<“destructingstudent.\n〞;}*/protected:intsomeHours;floatgpa;};未完待续例题分析classTeacher{public:Teacher(){cout<<“constructingteacher.\n〞;}/*~Teacher(){cout<<“destructingteacher.\n〞;}*/};classTutorPair{public:TutorPair(){cout<<“construcingtutorpair.\n〞;noMettings=0;}/*~TutorPair(){cout<<“destructingtutorpair.\n〞;}*/protected:Studentstudent;Teacherteacher;intnoMettings;//会晤次数};例题分析未完待续voidmain(){TutorPairtp;cout<<“backinmain.\n〞;}程序运行结果如下:constructingstudent.constructingteacher.constructingtutorpair.backinmain./*destructingtutorpair.destructingteacher.destructingstudent.*/例题分析提示例题分析提示:1〕一个类可能在构造函数中分配资源,这些资源需要在对象不复存在以前被释放。例如,如果构造函数翻开了一个文件,文件就需要被关闭。析构函数允许类自动完成这些清理工作,不必调用其他成员函数。2〕析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。只是在类对象生命期结束的时候,由系统自动调用。构造函数可以有参数,可以重载。3〕析构函数以调用构造函数相反的顺序被调用。即当主函数运行到结束的花括号处时,析构函数依次被调用。可参考例题2-7中的加注释(/*…*/)的斜体局部

前面介绍了成员函数与对象的声明方式。事实上,成员函数的参数和返回值不仅可以是整型、字符型和指针类型等,而且可以把对象作为参数和返回值。下面通过例子进行说明:

对象与成员函数例2-8对象作为参数和返回值的例子。#include<iostream.h>classDistance//声明类Distance{intmile,yard;public:Distance();//声明构造函数Distance(int,int);//声明重载的构造函数voidget_value();//声明成员函数Distanceadd_value(Distance);//声明成员函数add_value//参数为Distance类的对象,返回值也是Distance类的对象voiddisplay();//声明成员函数};未完待续例题分析Distance::Distance()//定义构造函数体{mile=0;yard=0;}Distance::Distance(intv1,intv2)//定义重载的构造函数体{mile=v1;yard=v2;}voidDistance::get_value()//定义成员函数体{cout<<“Entermile:〞;cin>>mile;cout<<“Enteryard:〞;cin>>yard;}未完待续例题分析DistanceDistance::add_value(DistanceA)//定义成员函数体{DistanceB;B.yard=yard+A.yard;B.mile=0;if(B.yard>=1760){B.mile=1;B.yard=-1760;}B.mile+=mile+A.mile;returnB;}voidDistance::display()//定义成员函数体{cout<<mile<<“miles〞<<yard<<“yards〞<<endl;}未完待续例题分析voidmain(){DistanceD(10,100);//定义对象D,并传入初值DistanceF,G;//定义对象F和GF.get_value();G=D.add_value(F);//G=D+Fcout<<“Thefirstdistance:〞;D.display();cout<<“Theseconddistance:〞;F.display();cout<<“Thethirddistance:〞;G.display();}例题分析Endthis指针。静态数据成员和成员函数。this指针和静态成员this指针this指针是一个隐含的指针,每个成员函数都有一个this指针变量。this指针用于指向以该成员函数所属类定义的对象,当某个对象调用成员函数时,成员函数的this指针便指向该对象。因此,不同的对象调用同一个成员函数时,编译器便依成员函数this指针所指向的不同对象来确定应该引用哪一个对象的数据成员。(例如,2-8中对成员函数display()的调用)静态数据成员和成员函数在C++中,当用一个类定义多个对象时,每个对象都拥有各自的数据成员,而所有对象共享同一个成员函数。当我们调用成员函数时,系统会根据不同的对象去使用相应的数据成员。C++中还有另一类数据成员---静态数据成员,它与前面所介绍的类成员不同。这种数据成员对类的所有对象只有一个。静态数据成员可以解决数据共享问题。这里需要注意的是,用全局变量解决数据共享有不平安的一面。静态数据成员不仅可以实现多个对象之间的数据共享,而且使用静态数据成员也不会破坏数据隐藏的原那么,即保证了数据的平安。静态数据成员和成员函数静态数据成员的特点如下:1〕静态数据成员是类中所有对象共享的成员,而不是某个对象的成员。2〕应用静态数据成员可以节省内存,因为它是所有对象所共有的。对于多个对象来说,静态数据成员只存储在一处,供所有对象共用。3〕静态数据成员的值对每个对象都是一样的。它的值可以更新,只要对静态数据成员的值更新一次,即可保证所有对象存取更新后的值相同。定义类的静态数据成员方法是,在变量定义的前面加上关键字static。定义为静态数据成员的变量应在定义类的对象前进行初始化。几点提示静态数据成员和成员函数提示:静态数据成员在类中说明。静态数据成员在类外声明,并初始化。其初始化格式为:数据类型类名::静态变量=初值;例如:classA{private:

inta,b,c;public:staticints;//说明静态数据成员

staticvoidfun();//静态成员函数};intA::s=0;//静态数据成员在类外声明,并初始化静态数据成员和成员函数例题分析例2-9静态数据成员初始化的例子。#include<iostream.h>classobjcount{private:staticintcount;public:objcount(){count++;}intget(){returncount;}程序的运行结果如下:34voidmain(){objcounta1,a2,a3;cout<<a1.get()<<endl;objcounta4;cout<<a3.get<<endl;}在类中,值使用静态数据成员的函数可以定义为静态成员函数。静态成员函数的定义方法是:在原函数定义前加static关键字。静态成员函数也是属于类的静态成员,而非对象的成员。因此,对静态成员的引用不需要用对象名。在静态成员函数的实现中不能直接引用类中说明的非静态成员,其格式如下:static数据类型函数名〔〕{函数体}几点提示静态成员函数

提示:静态成员没有this指针,即静态成员函数不与某个具体对象相联系。在静态成员函数中只能访问静态数据成员。静态数据成员函数不通过对象而直接调用。而非静态成员函数,必须与某个对象相联系。成员函数是属于类的。在main()函数中,调用静态成员函数时使用如下格式:<类名>::<静态成员函数名>(<参数表>)静态成员函数例题例2-10分析以下程序的输出结果#include<iostream.h>classperson{public:person(inta){A=a; B+=a;} staticvoidf1(personm);private:intA;staticintB;};voidperson::f1(personm){cout<<"A="<<m.A<<endl;cout<<"B="<<B<<endl;}intperson::B=0;voidmain(){personp(10),Q(20);person::f1(p);person::f1(Q);}友元函数前面介绍过,只有类中的成员函数才可以访问类中的私类型数据和保护类型数据。为了方便使用,C++语言提供了一种特殊的函数,允许访问类的私有和保护类型数据,即友元函数(friendfunction)。友元函数的声明方式如下:class类名称{typevars;…..public:

friend函数类型函数名称();//友元函数…..};例题分析例2-11下面是关于友元函数的例如#include<iostream.h>classCPoint{public:CPoint(){m_x=m_y=0;}CPoint(unsignedx,unsignedy){ m_x=x; m_y=y;}voidPrint(){ cout<<"Point("<<m_x<<","<<m_y<<")"<<endl;}friendCPointInflate(CPoint&pt,intnOffset);//声明一个友元函数private:unsignedm_x,m_y;};未完待续CPointInflate(CPoint&pt,intnOffset){CPointptTemp=pt;ptTemp.m_x+=nOffset;ptTemp.m_y+=nOffset;returnptTemp;}voidmain(){CPointpt(10,20);pt.Print();pt=Inflate(pt,3);pt.Print();}例题分析2.7类的继承

面向对象程序设计中,允许某个类继承其他类的属性。被继承的类称为基类或父类,继承的类称为派生类或子类。继承是C++语言的一种重要机制,这种机制自动地为一个类提供来自另一个类的操作和数据结构,从而使得程序员只需在新类中定义已有类中没有的成分来建立新类。1、派生类与基类

从一个基类定义一个派生类的格式如下:class<派生类名>:[<继承方式>]<基类名>{[<派生类的成员>]};例题分析例2-12以下是一个简单的类继承的例子classParent{inti;protected:intx;public:Parent();voidchange();voiddisplay();};Parent::Parent(){x=0;i=0;}voidParent::change(){x++;i++;}voidParent::display(){cout<<“x=“<<x<<endl;}classSon:publicParent{public:voidmodify();};voidSon::modify(){x++;}几点说明经过类继承,派生类Son具有以下特性:保护数据x。公有成员函数Parent〔〕。公有成员函数change〔〕。公有成员函数modify〔〕。公有成员函数display〔〕。从这个例子可以看出,尽管派生类Son中只声明了一个函数,但却继承了基类的很多特性。此外,派生类可以使用基类中的公有和保护数据,但基类却不可以使用派生类的函数。例题分析派生类的构造函数和析构函数

提示:在建立派生类对象时,先执行基类的构造函数,然后执行派生类的构造函数。但对于析构函数来说,其顺序则相反,先执行派生类的析构函数,而后执行基类的析构函数。如果在对派生类进行初始化时,需要对基类设置初值,可按下列格式进行:

<派生类名>([<构造函数形式参数表>]):<基类构造函数>([<形式参数表>]){…}

多重派生类基类派生类1派生类N继承继承……图2-6多重派生类前面介绍的类继承都是基类、派生类的一对一关系。事实上,基类与派生类之间可以有复杂的多对多关系。这里将要介绍的多重派生类就是从一个基类派生出多个不同派生类的一对多关系,如图2-6所示。类的多继承基类1派生类基类N继承继承……图2-7类的多继承2.8重载重载包含函数重载和操作符重载,是C++语言所提供的一个重要特性。函数重载函数重载是指在一个程序内声明多个名称相同的函数,这些函数可以完成不同的功能,并可以带有不同类型、不同数目的参数及返回值。使用函数重载可以减轻用户的记忆负担,使程序结构简单、易懂。请看例题操作符重载操作符重载与函数重载的功能一致。操作符重载是将C++语言中的已有操作符赋予新的功能,但与该操作符的本来含义不冲突,使用时只需根据操作符出现的位置来判断其具体执行哪一种运算。使用操作符重载时,必须用以下的方式来声明成员函数:

函数类型operator#(形参表)其中,operator是关键字,#表示欲定义的运算符,函数类型指明返回值类型,通常与类类型一致或为void类型。请看例题2.9多态性多态性指的是一个接口名称具有多种功能,是面向对象程序设计的重要特性。前面介绍的函数重载和操作符重载都是用来表示名称相同而功能不同的,因此属于程序编译时的多态性。在C++语言中,还有一种运行时的多态性,又称为虚函数。以下介绍的就是这种多态性。虚函数虚函数指的是某个函数在基类中被声明为virtual,而在派生类中又重新定义了此函数。声明虚函数的语法形式为:

virtual函数类型函数名称(){……}纯虚函数知识要点:在实际应用中,C++语言设计虚拟函数通常都是用基类定义某事件的接口及数据定义,而在派生类中定义处理该事件的方法,这样就可以实现单一接口,多种功能。由于在基类中定义的虚拟函数通常只是完成初始化或定义接口的目的,一般不执行具体功能,所以为了降低程序的复杂程度并节省内存空间,可以让此函数等于零,又称为纯虚函数。重点和难点引用的使用。

传递函数参数的方式。对象的概念及特性。构造函数和析构函数。类的静态数据成员和成员函数、友元函数。类的继承和派生。重载、多态性。虚函数。讨论

在例子2-3运行结果中是否实现了变量a和b的交换,为什么?在例子2-4和例子2-5的运行结果中是否实现了变量a和b的交换,为什么?两个例子有何异同?为什么要对运算符重载?虚函数在实现多态性方面同重载函数有什么不同?如何通过派生

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论