关闭

关闭

关闭

封号提示

内容

首页 Visual C++ 6.0开发指南第1章.pdf

Visual C++ 6.0开发指南第1章.pdf

Visual C++ 6.0开发指南第1章.pdf

上传者: Kevin125 2011-10-10 评分 0 0 0 0 0 0 暂无简介 简介 举报

简介:本文档为《Visual C++ 6.0开发指南第1章pdf》,可适用于IT/计算机领域,主题内容包含第章VisualC与面向对象技术概述第章VisualC与面向对象技术概述Windows编程采用的是面向对象的方法(ObjecOrientedProg符等。

第章VisualC与面向对象技术概述第章VisualC与面向对象技术概述Windows编程采用的是面向对象的方法(ObjecOrientedProgramming简称OOP)要编写真正的Windows应用程序就必须对OOP有一定了解。而VisualC是Windows环境下最主要的C开发环境它支持面向对象编程并提供可视化编程环境。面向对象技术面向对象技术不只是一种程序设计的方法而是建立客观事务模型分析复杂事务的思想方法。面向对象方法的本质就是强调从客观世界中固有的事物出发来构造系统用人类常用的思维方式来认识、理解和描述客观事物。面向对象的基本概念要理解面向对象技术必须了解个概念即对象(object)、类(class)和面向对象(objectoriented)。.对象对象是客观世界中的实体或者概念可以将对象理解为事物。对象可以是系统中任何被观察到的实体在构造应用系统的过程中程序员分析问题并对解决该问题所需的组件形成一个观察模型即产生一个抽象的对象表示。对象具有静态和动态的特征面向对象技术是将静态特征映射为对象的属性、动态特征映射为对象的方法。图所示为一个复数对象的模型。在建立客观事务的软件模型时可以将对象的属性抽象为变量将对象方法抽象为函数。.类类是一个抽象的概念用于描述某一类对象所共有的、本质的属性和类行为。对程序开发而言类是数据结构和函数的结合体是结构体的扩展。“类”这一概念十分有利于全面地分析客观事务建立客观事务的模型。现实世界中的实体可以抽象出类别的概念。对应于计算机世界就有一个类(class)的概念实部虚部加法减法乘法求模对象属性对象方法复数对象模型图复数对象的模型VisualC开发指南因为类是一个抽象的概念的对应体所以计算机不给它分配内存只给对象分配内存。计算机世界与现实世界之间的对应关系如图所示。对象类计算机世界实体抽象类别现实世界客观世界抽象抽象实例化映射主观世界图对象、实体与类的关系类和对象的关系就如同整数与、、的关系一样即对象是类的实例化。可以理解为类是一个抽象的框架类中变量赋了值就是对象。同样是复数其类和对象可表示为表所示。表复数的类与对象类对象名称复数复数c=(i)属性具有实部和虚部实部a=虚部b=行为能进行复数允许的运算cc,cc,…….面向对象与面向过程传统的编程方法被称作面向过程编程。在C语言中利用面向过程的编程是将一个问题看作一系列要完成的事情。这种面向过程的程序设计方法不能反映人们解决问题的思路。其设计方法自顶向下、功能分解其开发过程是从“做什么”到“如何做”。这种方法存在固有的缺陷主要表现为程序的可重用性差、程序维护的一致性差。面向对象的程序是由若干“对象”有机结合而成。这些对象可以互相通信、协调、配合从而共同完成整个程序的任务和功能。换句话说面向过程的编程方法中程序是由数据和函数组成的而面向对象编程中程序是由对象组成的。在描述一个事物时其属性和行为往往是不能分割的。事物的属性有时会影响事物的行为而事物的行为也会改变事物的属性。对象特有的变量和对象的功能函数也是密不可分的在对象内部的运行机制中它们往往是有机地结合在一起。在面向过程的程序设计中并不支持变量和函数的结合。而面向对象的程序设计中由于有了类的概念使得程序设计更易实现。面向对象与面向过程程序设计的区别如表所示。第章VisualC与面向对象技术概述表面向对象与面向过程程序设计面向过程面向对象以功能为中心以数据为中心按照预定的顺序执行事件驱动功能不稳定数据具有稳定性面向对象程序设计方法的核心可表示如下。设计思路:对客观事物的抽象。程序特点:对类(对象的存在形式)进行结构化程序设计。类提供简单的对外接口。面向对象技术的基本特征到目前为止对面向对象的概念的定义仍有不同的认识但它的继承性、封装性、多态性等特征基本上得到认可。.继承性真实的对象不是孤立存在的每个对象都与其他一个或多个对象相关。事实上当描述一个新对象时往往要指出该新对象的特征与已存在的对象的特征有何不同。对于面向对象来说继承性是指一个新类可以从现有的类中派生出来新类具有父类中的所有特性直接继承父类的方法和数据新类的对象可以调用该类及父类的成员变量和成员函数。继承分单一继承和多重继承。所谓多重继承是指一个类可以从一个以上的类中派生出来。例如某公司的某职员既是工程师又是管理人员则他应同时具有技术人员和管理人员的特征。很多面向对象的语言都不支持多重继承但C支持。.封装性封装是指把数据和方法放在同一个对象中对数据的存取只能通过该对象本身的方法来进行。封装性的实质就是将类包装起来将要保护的变量和函数用私有成员描述可供外界调用的部分用公有成员描述。.多态性多态性是指同一消息被不同的对象接收时可以解释为不同意义的能力也就是说同样的消息被不同类的对象接收时会产生完全不同的行为。利用多态性可以发送一般的消息而把所有实现的细节留给接收消息的对象去解决。说明:操作符的重载也具有多态性。面向对象设计语言与VisualC.面向对象设计语言面向对象设计语言的产生及发展如下。VisualC开发指南世纪年代Simula语言就具有了类和对象的概念。年代初美国XeroxPaloAlto研究中心推出了Smalltalk它完整地体现并进一步丰富了面向对象的概念。混合型面向对象程序设计语言出现如C、C#这类语言一般是在其他语言的基础上开发出来的。纯面向对象程序设计语言出现如Java语言。其中C语言是在C语言基础上扩充的是C语言的超集它是支持OOP的最主要代表语言。.VisualC简史VisualC的根源不是开始于Microsoft公司而是Borland公司。VisualC的发展过程可简单表示如下。MSCC:首次把编译器指明为CC包含了MFC(MicrosoftFoundationClass)使C语言成为最成功的OOP语言大大促进了OOP的软件开发。MSCC(VisualC):提供了Windows风格的编辑器和调试器含有MFC与MFC相比增加了动态链接库DLL支持和OLE(ObjectLinkingandEmbedding)。VisualC:增强对位编程支持。VisualC:将资源集成到开发工作台(WorkBench)中使界面更好且支持Windows、WindowsNT、Windows。VisualC:支持多重平台和平台间的开发简化了在多重平台间的移植。VisualC:增加了许多重要功能如ActiveX编程、Internet编程等。VisualC:功能更强MFC类库更丰富。对数据库支持的增强包括ADO(ActiveXDataObject)、OLEDatabase的数据控件等。VisualCNET:包括VisualCNET、VisualCNET、VisualCNET等几个版本为面向Windows和NETFramework的开发人员提供了更多的功能。在所有领域(包括语言、编译器和核心库)都进行了关键改进。这些改进使C开发人员能够更有效地使用CLR(公共语言运行时)优化代码的性能提高应用程序的安全性。对于纯粹的基于Windwos操作系统的应用程序开发VisualC版本仍然是C面向对象编程的最佳选择。.为什么要学习和使用VisualC最近有许多专业的程序员放弃了VisualC而改用了其他产品提供的RAD(快速应用开发)环境。许多人认为VisualC太古老、太繁琐、学起来太困难了。VisualC的学习周期确实比其他语言要长然而VisualC具备很多优点如下。灵活性:使用VisualC程序员可以彻底地控制整个开发环境。其他语言则更多地趋向于保护程序员而这种保护作用有时会成为开发工作的障碍。第章VisualC与面向对象技术概述能够创建短小高效的程序:VisualC程序可以开发出运行速度很快的程序并且避免了汇编语言存在的各种问题。应用范围广:C是编写诸如操作系统、设备驱动程序以及动态链接库(DLL)的强大语言这种领域代码的开发依然是VisualC的主战场。说明:VB的数据库支持功能较强而VisualC的图形功能较强。VisualC是真正的面向对象编程。C的面向对象特性作为支持OOP的最主要代表语言C语言具有面向对象技术的所有特性并以类和对象为基础支持类的继承、封装和多态特性。C中的类与对象C中的类是用户定义的一种数据类型是在Struct类型基础上的扩展。Struct类型只是声明了一些数据而类不仅包含通常的数据还包括对数据的操作。C称类的属性为数据成员称类的操作(方法)为成员函数。类封装了数据成员和成员函数。对象是声明属于某一特定类的变量也称为类的实例。类的所有对象具有相同的属性和操作(方法)。.C中类的声明与实现在C中声明类的一般形式如下。class类名{private:私有数据和函数public:公有数据和函数protected:保护数据和函数}类声明以关键字class开始其后跟类名。类所声明的内容用花括号括起来右花括号后的分号作为类声明语句的结束标志。花括号“{}”之间的内容称为类体。类中定义的数据和函数称为这个类的成员(数据成员和成员函数)。类成员均具有一个属性叫做访问权限通过它前面的关键字来定义。顾名思义关键字private、public和protected以后的成员的访问权限分别是私有、公有和保护的把这些成员分别叫做私有成员、公有成员和保护成员。private部分的数据成员或成员函数在类之外是不能访问的只有类中的成员函数才能访VisualC开发指南问。public部分的数据成员和成员函数可被程序中的任何函数或语句存取。protected部分说明的成员或成员函数在类之外是不能存取的只有类的成员函数及其子类可以存取。说明:如果没有使用关键字则所有成员默认声明为private权限。在实际编程中public成员多为成员函数用于提供与外界的接口只有通过这个接口才能实现对private成员的存取。如一个简单的类的声明如下。classPerson{private:charNameintAgecharSexpublic:voidRegister(char*name,intage,charsex)voidShowMe()}该例中声明了Person类定义了个私有数据成员它们只能通过Register函数存取。上面的例子中仅给出了成员函数Register的函数原型而没有定义函数。对于使用者通常只需要了解函数原型中给出的函数名、返回类型、参数个数和参数类型即可。成员函数的具体实现可以放在类声明之外定义在定义成员函数时必须在函数名前面加上类名并用作用分隔符“::”分隔以便让编译程序知道该函数属于哪一类。例如:vidPerson::Register(char*name,intage,charsex){strcpy(Name,name)Age=ageSex=(sex=='m''m':'f')}.C中类的对象的声明与使用声明了一个类即定义了一个用户数据类型。为了使用类还必须说明类的变量即类的实例(instance)或对象(object)。声明对象的语法类似于声明变量如:PersonTheperson也可以声明由多个对象组成的数组:Personpersonarray还有一种方法是在声明类的同时声明对象如:classExampleclass{intypublic:intx第章VisualC与面向对象技术概述voidshow()}myclass这样就说明了myclass是Exampleclass类的一个对象。声明了类的对象之后就可以对该类的数据成员和成员函数进行访问。注意:类中的成员是不能直接访问的必须通过该类的对象来访问。类成员的访问方法是:在对象和public数据成员或成员函数之间加上“”。如:myclassxmyclassshow()不能直接访问类的私有成员如myclassy是错误的。还可以通过说明对象指针并通过指针调用类的成员如:Exampleclass*classPointer=myclassclassPointer>show()通过classPointer指针调用成员函数show()。C类的继承与派生从一个或多个以前定义的类(基类)产生新类的过程称为派生这个新类又称为派生类。类的继承(inheritance)是指新类从基类那里得到基类的特征也就是继承基类的数据和函数。而派生的新类同时也可以增加或重新定义数据和操作这就产生了类的层次性。当从现存类中派生出新类时可以对派生类增加新的数据成员、增加新的成员函数、重新定义已有的成员函数、改变现有成员的属性。.单一继承与多重继承如果一个派生类可以同时有多个基类则称为多重继承(multipleinheritance)这时的派生类同时得到了多个已有类的特征。如果一个派生类只有一个直接基类则称为单一继承(singleinheritance)。单一继承和多重继承类的层次关系如图所示。基类基类基类n派生类派生类……多重继承基类派生类派生类单继承图单一继承和多重继承可见一个基类可以直接派生出多个派生类。而派生出来的新类同样可以作为基类再继续派生出更新的类依此类推形成一个层次结构。VisualC开发指南.派生类的定义格式派生类的格式定义可简单表示如下。class派生类名:访问权限基类名访问限定符基类名……访问限定符基类名n{private:成员表派生类增加或替代的私有成员public:成员表派生类增加或替代的公有成员protected:成员表派生类增加或替代的保护成员}分号不可少其中基类、基类、……是已声明的类。可以使用的访问限定符包括public、private和protected。在派生类定义的类体中给出的成员称为派生类成员它们是新增加的数据和函数成员。这些新增加的成员是派生类对基类的发展它们给派生类添加了不同于基类的新的属性和功能。派生类成员包括新添加的也包括通过屏蔽作用取代基类成员的更新成员。类的派生过程可表示为图所示。吸收基类的成员不论是数据成员还是函数成员除构造函数与析构函数外全盘接收改造基类成员声明一个和某基类成员同名的新成员派生类中的新成员就屏蔽了基类同名成员称为同名覆盖(override)发展新成员派生类新成员必须与基类成员不同名它的加入保证派生类在功能上有所发展。重写构造函数与析构函数图类的派生过程.派生类的继承方式派生类对基类的访问控制也是种:公有(public)方式、保护(protected)方式和私有(private)方式称为公有继承、保护继承和私有继承。在派生类的定义中基类前所加的访问限定符有两方面含义。派生类成员(新增成员)函数对基类(继承来的)成员的访问(调用和操作)。从派生类对象之外对派生类对象中的基类成员的访问。各继承方式的访问权限如表所示。第章VisualC与面向对象技术概述表各继承方式的访问权限基类成员访问权继承方式派生类中对基类成员的访问权外部函数的访问权publicpublic可以直接访问protectedprotected不可直接访问publicprivateprivate不可直接访问publicprotected不可直接访问protectedprotected不可直接访问protectedprivateprivate不可直接访问public不可访问不可直接访问protected不可访问不可直接访问privateprivate不可访问不可直接访问.派生类的构造函数与析构函数派生类构造函数的一般形式如下:派生类名::派生类名(参数总表):基类名(参数表)…基类名n(参数表n)内嵌对象名(对象参数表)…内嵌对象名m(对象参数表m){派生类新增加成员的初始化}派生类构造函数的执行次序如下。首先调用基类构造函数调用顺序按照它们被继承时声明的基类名顺序执行。其次调用内嵌对象构造函数调用次序按各个对象在派生类内声明的顺序。最后执行派生类构造函数体中的内容。派生类与基类的析构函数没有什么联系彼此独立派生类或基类的析构函数只作各自类对象消亡前的善后工作。派生类析构函数的执行过程与构造函数执行过程相反执行顺序如下。首先执行派生类析构函数。然后执行内嵌对象的析构函数。最后执行基类析构函数。类的继承实例为了使读者对继承的概念有直观地认识下面给出一个多重继承的实例。已知时间类TimeType和日期类DateType通过多重继承定义日期时间类DateTimeType。其中时间类TimeType的定义如下。classTimeType{inthour,minute,second时、分、秒public:VisualC开发指南TimeType(inth=,intm=,ints=)构造函数{hour=hminute=msecond=s}voiddisplay()输出时间{cout<<hour<<":"<<minute<<":"<<second<<endl}voidSetTime(inth,intm,ints)成员函数设置时间{hour=hminute=msecond=s}}日期类DateType的定义如下:classDateType{intmonth,day,year月、日、年public:DateType(intmo=,intd=,inty=)构造函数{month=moday=dyear=y}voiddisplay()输出日期{cout<<month<<""<<day<<""<<year<<endl}voidSetDate(intmo,intd,inty)成员函数设置日期{month=moday=dyear=y}}日期时间类DateTimeType由TimeType类和DateType类两个基类派生其定义如下:classDateTimeType:publicDateType,publicTimeType{public:DateTimeType(intmo=,intd=,inty=,inth=,intm=,ints=):DateType(mo,d,y),TimeType(h,m,s){}构造函数第章VisualC与面向对象技术概述voiddisplay()显示时间、日期{DateType::display()调用DateType类的display函数TimeType::display()调用TimeType类的display函数}}主函数中实现对日期时间类DateTimeType的调用测试代码如下:#include<iostream>usingnamespacestdintmain(){DateTimeTypedt(,,,,,)直接使用DateTimeType构造函数设置日期时间cout<<"DateTimeType类设定的日期、时间为:"<<endldtdisplay()dtSetDate(,,)调用基类的成员函数修改日期dtSetTime(,,)调用基类的成员函数修改时间cout<<"调用基类成员函数修改后的日期、时间为:"<<endldtdisplay()return}运行结果如图所示有关本程序的源程序可参见所附光盘。图程序运行结果在本实例中读者需要注意多重继承构造函数的声明以及对基类成员函数的访问。虚函数与多态多态性是指当同样的消息被不同的对象接收时会导致不同的行为。这里所说的消息是指对类成员函数的调用。函数重载实现了这种多态性。它是建立在虚函数的概念和方法之上通过虚函数来实现的。利用多态性能够发送一般形式的消息而所有实现的细节则留给接收消息的对象。.多态的基本概念多态性是面向对象程序设计的关键技术之一。若程序设计语言不支持多态性则不能称为面向对象的语言。利用多态性技术可以调用同一个函数名的函数实现完全不同的功能。在VisualC开发指南C中有两种多态性:编译时的多态性和运行时的多态性。编译时的多态性主要是通过函数的重载和运算符的重载来实现的。说明:重载是指允许存在多个同名函数而这些函数的参数表不同(或许参数个数不同或许参数类型不同或许两者都不同)。通过函数重载实现编译时多态的简单实例如下:voidmain(){intacharbfloatcmax(a)调用的函数为:intmax(intarr){……}max(b)调用的函数为:charmax(chararr){……}max(c)调用的函数为:floatmax(floatarr){……}}在该例中虽然同样调用了函数max()但由于其参数的类型不同实际调用了不同形式的函数即通过函数的重载实现了编译时的多态。运行时的多态性是指:在程序执行前无法根据函数名和参数来确定该调用哪一个函数必须在程序执行过程中根据执行的具体情况来动态地确定。它是通过类继承关系和虚函数来实现的其目的也是建立一种通用的程序。说明:通过封装可以隐藏实现细节使得代码模块化继承可以扩展已存在的代码模块(类)。它们的目的都是为实现代码重用。而多态则是为了实现接口重用。.虚函数虚函数是指:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。其声明格式如下。virtual函数返回类型函数名(参数表){函数体}关键字virtual指明该成员函数为虚函数。virtual仅用于类定义中如虚函数在类外定义不可加virtual。基类的成员函数一旦被声明为虚函数每一层派生类中该函数都保持虚函数特性在其派生类中其关键字virtual可省略。当在派生类中重新定义虚函数(也称覆盖)时不必加关键字virtual。但重新定义时不仅要同名而且它的参数表和返回类型要全部与基类中的虚函数相同。如果某类中的一个成员函数被说明为虚函数就意味着该成员函数在派生类中可能有不同的函数实现。说明:虚函数与在图所示派生类的第二步改造类成员同名覆盖(override)有关:如未加关键字virtual则是普通的派生类中的新成员函数覆盖基类同名成员函数(当然参数表必须一样否则是重载)可称为同名覆盖函数也就不能实现运行时的多态性。第章VisualC与面向对象技术概述虚函数实现运行时多态实例下面给出一个实例该实例利用虚函数实现运行时的多态。通过本实例读者可以体验虚函数实现的“单界面多方法”的概念。现有基类figure存放二维对象(三角形、矩形和圆形三个类)的各维数据并由setdim()函数设置数据它是标准成员函数。还有一个虚函数showarea()用于计算显示图形的面积。因为计算三角形、矩形和圆形个类对象的面积的方法是不同的需重新定义。Figure类的实现如下:classfigure基类{protected:doublex,y成员变量public:voidsetdim(doublei,doublej=)设置图形参数{x=iy=j}virtualvoidshowarea()虚函数计算面积{cout<<"Noareacomputationdefinedforthisclassn"}}三角形、矩形和圆形个类分别需要覆盖虚函数showarea代码如下:classtriangle:publicfigure三角形类{public:voidshowarea()覆盖虚函数{cout<<"三角形的高:"<<x<<"底边长:"<<y<<"面积为:"<<x**y<<endl}}classsquare:publicfigure矩形类{public:voidshowarea()覆盖虚函数{cout<<"矩形的长:"<<x<<"矩形宽:"<<y<<"面积为:"<<x*y<<endl}}classcircle:publicfigure圆形类{public:VisualC开发指南voidshowarea()覆盖虚函数{cout<<"圆形的半径:"<<x<<"圆形面积为:"<<*x*x<<endl}}在主函数中可以通过相同方式调用具有不同功能的同名函数即虚函数showarea代码如下:intmain(){figure*ptrianglet三角形类对象squares矩形类对象circlec圆形类对象p=tp>setdim(,)设置三角形的参数p>showarea()计算三角形的面积p=sp>setdim(,)设置矩形的参数p>showarea()计算矩形的面积p=cp>setdim()设置圆形的参数p>showarea()计算圆形的面积return}运行结果如图所示有关本程序的源程序可参见所附光盘。图程序运行结果在本例中同样是通过figure类指针调用showarea()函数但由于指针对象的不同实现的虚函数showarea的形式也就不同。程序对虚函数的调用过程可表示为图所示。一般而言可将类中具有共性的成员函数声明为虚函数派生类定义虚函数的时候必须保证函数的返回值类型和参数与基类中的声明完全一致。注意:只能通过对象指针或引用来调用虚函数才能实现程序运行时的多态不能定义虚构造函数但可以定义虚析构函数。第章VisualC与面向对象技术概述消息对象行为p>showarea()triangletshowarea()squaresshowarea()circlecshowarea()计算并显示三角形的面积计算并显示矩形的面积计算并显示圆的面积图虚函数调用过程动态联编与虚函数表所谓联编是指:计算机程序自身彼此关联的过程是把一个标识符名和一个存储地址联系在一起的过程也就是把一条消息和一个对象的操作相结合的过程。C中应用程序的联编有两种形式:静态联编和动态联编。静态联编:如果使用对象名和成员选择运算符“”引用特定的一个对象来调用虚函数则被调用的虚函数是在编译时确定的这时称为静态联编。动态联编:如果使用基类指针或引用指明派生类对象并使用该指针调用虚函数(成员选择符用箭头号“”)则程序动态地(运行时)选择该派生类的虚函数称为动态联编。在面向过程程序设计中所有程序都采用静态联编来实现。静态联编的特点是函数调用速度快、效率较高但是编程灵活性不够。动态联编虽然效率较静态联编低但是能实现更灵活、更易维护、逻辑关系更清晰的代码。C编译器在编译含有一个或几个虚函数的类及其派生类时对该类建立虚函数表(Virtualfunctiontablevtable)。虚函数表放置虚函数的地址使执行程序正确选择每次执行时应使用的虚函数。在每个包含虚函数的类中编译器秘密地放置了一个称之为vpointer(缩写为VPTR)的指针指向这个对象的VTABLE。所以无论这个对象包含一个或是多少虚函数编译器都只放置一个VPTR即可。VPTR由编译器在构造函数中秘密插入的代码来完成初始化指向相应的VTABLE这样对象就“知道”自己是什么类型了。VPTR都在对象的相同位置常常是对象的开头。这样编译器可以容易地找到对象的VTABLE并获取函数体的地址。每当创建一个包含虚函数的类或从包含虚函数的类派生一个类时编译器就为这个类创建一个惟一的VTABLE。假如在派生类中没有对在基类中的某个虚函数进行重写(overriding)那么还使用基类的这个虚函数的地址如一个基类BASE有两个虚函数func和func它有两个派生类A和B均对虚函数func进行了重写其虚函数表可简单表示为图所示。说明:VPTR指向的VTABLE其实就是一个函数指针的数组。现在VPTR正指向它的第一个元素那是一个函数指针。如果VPTR向后偏移一个Void指针长度的话那么它应该指向了VTABLE中的第二个函数指针了。这看来就像是一个指针连成的链从当前指针获取它指向的下一个指针这样才能“顺藤摸瓜”。VisualC开发指南基类对象basevptr派生类A对象avptr派生类B对象bvptr(*vfunc)()(*vfunc)()(*vfunc)()(*vfunc)()(*vfunc)()(*vfunc)()base::funcbase::funcbase::funca::funcbase::funcb::func图虚函数表示意图C的一些重要要素VisualC应用程序开发是以C语言为基础的有关C语言的基本知识及基础语法本书不作详细介绍本节只是探讨一些在VisualC程序开发中经常用到的也是容易忽视的C的一些要素。类的静态成员类的静态成员是指用关键词static定义的类的成员。一旦把类的成员声明为静态则无论该类创建了多少个对象都只是静态成员的一个拷贝也就是说静态成员被类的所有对象共享。因此静态成员属于类而不属于类的对象。.静态数据成员静态数据成员要在类的定义中声明但静态数据成员的初始化要在类外的全局范围内进行而不能在类的构造函数中进行。使用静态数据成员可以节省内存因为它是所有对象所公有的因此对多个对象来说静态数据成员只存储一处供所有对象共用。静态数据成员的值对每个对象都是一样的但它的值是可以更新的。只要对静态数据成员的值更新一次就可以保证所有对象存取更新后的值从而提高时间效率。静态数据成员的使用方法和注意事项如下。静态数据成员在定义或说明时前面加关键字static如publicstaticintcount。静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下。<数据类型><类名>::<静态数据成员名>=<值>注意:初始化在类体外进行而前面不加static以免与一般静态变量或对象相混淆。且初始化时不加该成员的访问权限控制符privatepublic等另外初始化时使用作用域运算符来标明它所属类因此静态数据成员是类的成员而不是对象的成员。第章VisualC与面向对象技术概述静态数据成员是静态存储的它是静态生存期必须对它进行初始化。引用静态数据成员时应采用如下格式。<类名>::<静态成员名>.静态成员函数对于只使用静态数据成员的成员函数可以将其声明为静态成员函数。静态成员函数的访问也可以不通过对象而直接调用。直接调用时必须指明它所在的类这样就明确该函数是静态成员函数且函数只调用类的静态数据成员只与类联系而不属于任何对象。说明:C会区分两种类型的成员函数静态成员函数和非静态成员函数。这两者之间的一个重大区别是静态成员函数不接受隐含的this指针所以它无法访问自己类的非静态成员。有关this指针可参见节。声明方法与静态数据成员一样前面加上关键词static。如:staticintshow()。根据类静态成员的特性静态成员的使用主要在以下几个方面。存储链表的第一个或者最后一个成员的内存地址。用于保存对象的个数。作为一个标记标记一些动作是否发生例如文件的打开状态、打印机的使用状态等。const常量在类中可以使用const关键字定义一个常量。const数据成员的声明必须包含初值而且这个初值必须是常量表达式const常量的值在作用域内保持不变例如:constintmaxSize=constintintArray={,,,,,}const成员仅存在惟一的一份实体const成员在编译期间就对表达式进行初始化。const成员本质上就是一种只读(readonly)的静态成员的应用访问时必须使用类的名称而不能使用类对象的名称。用关键字const修饰一个指针时根据其位置的不同有不同的含义。例如可以声明一个指向常量的指针:constchar*ptr=“Pointtoconstantstring”此时指针ptr所指向的对象不能被改变但ptr本身可以被改变。有了以上声明后下面的运算是非法的:str='a'也可声明常量指针:char*constqtr=“Aconstantpointer”VisualC开发指南此时该指针不能指向其他对象因此下面的赋值是非法的:qtr="Hi,there!"修饰符const多用于修饰函数的指针或引用参数以防止在编程中无意识地改变其值。说明:可以将const常量理解为readonlystatic即它是一个静态数据成员但是只读的即用户不能改写其值在定义时就指定。this指针对于每一个类的非静态成员函数都有一个隐含的this指针该指针指向调用该成员函数的实例对象。当成员函数使用对象中的非静态成员(无论是成员变量还是成员函数)它事实上是通过this指针来调用该成员的。一般情况下并不需要显式地使用this指针。如下面的类定义。classMyClass{public:voidseti(intnewi){i=newi}private:inti}对编译器而言成员函数seti的定义事实上如下面的代码所示。voidseti(intnewi){this>i=newi}在上例中this指针不必写成显式的但是有时必须写成显式的如在某些类型的链表管理中在需要返回当前调用的对象时等。将指向对象自身的指针作为参数传递给其他函数在实际编程中是一个很常用的技巧。注意:静态成员函数没有this指针。因为普通成员函数虽然在物理上只有一份拷贝但在逻辑上都认为一个对象有一份拷贝所以有this指针而静态成员函数在逻辑上也只有一份拷贝不属于具体的对象当然没有this指针。inline内联函数内联函数用标识符inline定义。程序编译时编译器就对内联函数在其调用处进行替换即将内联函数的实际代码插入在调用处从而消除执行过程中的函数调用开销。例如求最大值的内联函数可表示如下:第章VisualC与面向对象技术概述inlineintmax(intx,inty){if(x>y)returnxelsereturny}说明:如果在声明类的同时在类体内给出成员函数的定义则默认为内联函数。与非内联函数不同如果改变一个内联函数则所有调用它的源文件都要重新编译使得函数变成内联函数不改变其含义只是影响目标码的速度和长度。因此内联函数通常用于小而常用的函数特别是在一个循环中重复调用。在某种意义上内联函数类似于用#define预处理器命令定义的宏如上面定义的内联函数与下面的宏实现的功能基本相同:#defineMAX((intx,inty)(x>yx:y)然而内联函数与宏的处理方法不同。宏替换由预处理程序进行简单的字符串替换在替换过程中不进行语法的检查而内联函数由C编译器进行处理在插入代码之前即进行语法检查。注意:如果内联函数由多个源文件引用则应将该函数的实现代码放在头文件中而不能仅仅将该函数的原型声明放入头文件中。操作符引用类型当声明一个变量是另一个变量的别名时可以使用操作符。如下面的代码:intCount=intRefCount=CountRefCount被声明为int类型的引用并将其初始化为int类型变量Count。这个定义使RefCount和Count指向同一内存地址因此两个变量的数值总是相同的。当改变其中一个变量的值时会同时改变另一个变量的值。定义变量为某个变量的引用时必须用该声明类型的变量将它进行初始化且不能让一个引用变量引用不同的变量也不能用常量值来初始化引用变量除非声明该变量为const性的引用。也可以将函数的参数和返回类型声明为引用。如下面的函数:voidFunc(intParam)调用该函数时必须向函数中传递int类型的变量该变量用于初始化引用参数Param。在函数代码中Param是函数调用中传递的变量的别名这样函数内部对参数的修改会反映到函数外部被引用的变量。VisualC开发指南友元前面介绍过C类的封装一般将类中的数据成员声明为私有成员而外部则可以通过类的公有成员函数对私有成员进行访问。但有时类外的一些函数需要直接访问类的数据成员而用户又不想改变该数据成员在类中的访问权限这时就需要定义友元。注意:友元本身不是类的成员不属于任何类。在类的定义中声明友元时只要在友元的名称前加上friend即可。友元虽然不是类的成员但它是类的朋友可以直接访问类的所有成员。.友元函数如果友元是普通函数或另一个类的成员函数称为友元函数。友元函数是在类的外部访问类的所有成员的普通函数。一个函数可以是多个类的友元函数只需在各个类中分别声明即可。将一个函数声明为某类的友元函数的方法是:在类的定义中提供一个以friend开头的函数原型如下。friend<返回值类型><函数名>(<参数表>)友元函数的定义可以在类内也可以在类外。类外定义时与普通成员函数一样但不要加上类名(因为不属于该类)。友元函数不象成员函数那样在调用时使用对象名因为它不属于任何一个对象但使用友元

用户评论(0)

0/200

精彩专题

上传我的资料

每篇奖励 +2积分

资料评价:

/27
0下载券 下载 加入VIP, 送下载券

意见
反馈

立即扫码关注

爱问共享资料微信公众号

返回
顶部