版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+程序设计题解与上机指导C+-程序设计题解与上机指导v类的声明和定义类的声明和定义v构造函数、析构函数构造函数、析构函数v对象的创建和使用对象的创建和使用v对象的数组、指针、赋值和复制对象的数组、指针、赋值和复制v静态成员静态成员v共用数据的保护共用数据的保护v友元友元4.0 面向对象程序设计方法概述面向对象程序设计方法概述 对象对象属性(静态特征)属性(静态特征)行为行为 (动态特征)(动态特征)发消息发消息 让对象作什么。让对象作什么。 一个系统中有多个对象相互作用。一个系统中有多个对象相互作用。数据数据函数(方法、操作)函数(方法、操作)调用对象中的函数就是向调用对象中的函数就是向该对
2、象发消息,是对象的该对象发消息,是对象的少量的对外接口。少量的对外接口。封装性封装性 、信息隐蔽、信息隐蔽C+中中现实的问题空间现实的问题空间抽象:抽象:现实中对象现实中对象 类类 对象(类的一个实例)对象(类的一个实例)抽象出抽象出C+类型类型 变量变量继承性继承性 与与 软件重用软件重用利用一个已有的类建立一个新类利用一个已有的类建立一个新类多态性:由继承而产生的相关的不同的多态性:由继承而产生的相关的不同的类,其对象对同一消息会做出不同响应。类,其对象对同一消息会做出不同响应。数据数据 函数(算法)函数(算法) 对象对象1数据数据 函数(算法)函数(算法) 对象对象2系统(程序)系统(程
3、序)消息消息面向过程面向过程面向对象面向对象不同层次的抽象不同层次的抽象 基于对象就是基于类,基于对象就是基于类,C+中的类是实现面中的类是实现面向对象程序设计的基础。向对象程序设计的基础。面向对象软件开发面向对象软件开发规范的软件开发过程规范的软件开发过程(软件工程学要解决的问题):(软件工程学要解决的问题):1、面向对象分析、面向对象分析OOA:粗略的分析任务,归纳出有关对象:粗略的分析任务,归纳出有关对象2、面向对象设计、面向对象设计OOD:对类进行具体的设计,提出程序设计的:对类进行具体的设计,提出程序设计的思路和方法,包括算法。思路和方法,包括算法。3、面向对象编程、面向对象编程OO
4、P(选定一种语言写程序)(选定一种语言写程序)4、面向对象测试、面向对象测试OOT:以类作为测试的基本单元:以类作为测试的基本单元5、面向对象维护、面向对象维护OOSM:OOP的特性:的特性:u 抽象抽象u 封装和数据隐藏封装和数据隐藏u 继承继承u 多态多态u 代码的可重用性代码的可重用性 现实中对象现实中对象 类型类型 抽象抽象对象对象 类类型类类型定义定义4.1 类的声明和实现类的声明和实现类和对象的关系类和对象的关系u 类是对象的抽象,对象是类的具体实例。类是对象的抽象,对象是类的具体实例。u 某对象的类型称为某类,或某对象是某类类型的一某对象的类型称为某类,或某对象是某类类型的一个变
5、量。个变量。u 类类型是一种自定义的数据类型。类类型是一种自定义的数据类型。 用户要先提供类的声明和实现,然后才能使用。用户要先提供类的声明和实现,然后才能使用。类型是什么?类型是什么?指定类型完成了指定类型完成了3项工作:项工作:1、决定数据对象需要的内存数量、决定数据对象需要的内存数量2、决定如何解释内存中的位、决定如何解释内存中的位3、决定可使用数据对象执行的操作或方法、决定可使用数据对象执行的操作或方法l 对内置的基本类型来说,有关操作的信息被内置到编译器中。对内置的基本类型来说,有关操作的信息被内置到编译器中。l用户自定义的类型必须自己提供这些信息。用户自定义的类型必须自己提供这些信
6、息。l具有根据实际需要定制新数据类型的强大功能和灵活性。具有根据实际需要定制新数据类型的强大功能和灵活性。类是将抽象转换为用户定义类型的类是将抽象转换为用户定义类型的C+工具。它将数据和操纵数据工具。它将数据和操纵数据的方法组合成一个整体。的方法组合成一个整体。类规范由两部分组成:类规范由两部分组成: 类声明(类的蓝图)类声明(类的蓝图) 类方法定义:描述如何实现类成员函数。类方法定义:描述如何实现类成员函数。Class 类名类名 private:私有成员声明块;私有成员声明块; protected:保护成员声明块;保护成员声明块; public:公有成员声明块;公有成员声明块;一、类的声明:
7、一、类的声明:指出该类包括哪些数据和操作。指出该类包括哪些数据和操作。类头类头 类体类体数据成员数据成员成员函数成员函数成员访问属性成员访问属性修饰符修饰符分号结束分号结束class CStudent public : int num; char name20; char sex; void display( ); ;例:例:二、类成员访问属性:二、类成员访问属性:控制外部对类成员的访问,控制外部对类成员的访问,体现了类的数据隐藏性。体现了类的数据隐藏性。1) private: 限定为私有成员。限定为私有成员。 该成员只能被本类中的成员函数和类的友元函该成员只能被本类中的成员函数和类的友元函数
8、引用。数引用。 是类中的默认访问控制是类中的默认访问控制,可实现信息隐蔽。可实现信息隐蔽。2) public: 公用的成员公用的成员 可被本类中的成员函数引用,也可被类的作用可被本类中的成员函数引用,也可被类的作用域的其他函数引用。域的其他函数引用。 是类的对外接口是类的对外接口3) protected:受保护成员:受保护成员 不能被类外访问,但可以被派生类的成员函数不能被类外访问,但可以被派生类的成员函数访问。访问。 说明:说明: 每种说明符可在类体中使用多次。每种说明符可在类体中使用多次。 访问限定符的作用域是从该说明符出现开始到访问限定符的作用域是从该说明符出现开始到 下一个说明符之前或
9、类体结束之前结束。下一个说明符之前或类体结束之前结束。 如果在类体起始点无访问说明符,系统默认定如果在类体起始点无访问说明符,系统默认定 义为私有(义为私有(private)。)。 访问限定符访问限定符private(私有的)和(私有的)和protected (保护的)体现了类具有数据隐蔽性。(保护的)体现了类具有数据隐蔽性。 (Encapsulation)。)。class CStudent int num; public: float data; private: string name; char sex; public : void display( ); ;类和结构体的异同类和结构体的
10、异同 C+ 中扩展了中扩展了C 中结构体中结构体struct 的定义,使类和的定义,使类和结构体具有同样的功能。但结构体中默认的成员访问结构体具有同样的功能。但结构体中默认的成员访问限定为限定为public ,即它不天生具备信息隐蔽的特征。即它不天生具备信息隐蔽的特征。 struct CStudent . ;l 建议尽量使用类建议尽量使用类class 三、三、 类的实现类的实现-类的成员函数的定义类的成员函数的定义函数定义:函数定义:通常在类定义中,成员函数仅作声明。通常在类定义中,成员函数仅作声明。 函数定义通常在类的声明之后,在类外进行。函数定义通常在类的声明之后,在类外进行。格式如下:格
11、式如下: 返回值类型返回值类型 类名类名 : 函数名函数名(参数表参数表) /函数体函数体 其中运算符其中运算符“:”称为作用域运算符,它指出该函称为作用域运算符,它指出该函数是属于哪一个类的成员函数。数是属于哪一个类的成员函数。class CStudent int num; string name; char sex; int getnum三三return num; public : void display( ); ; void CStudent: display( ) cout “num”getnum三三endl; cout “name”nameendl; cout “sex”sexen
12、dl; : display三三 v类的成员具有类的成员具有 类作用域。类作用域。v它们不是全局函它们不是全局函数数 四、四、inline成员函数成员函数在类内定义的函数默认为内联函数在类内定义的函数默认为内联函数在类内用在类内用inline 声明的函数,在类外定义,声明的函数,在类外定义, 前面加前面加inline。例:例:class CStudent int num; public : void display1三三 cout“hello”endl; inline void display2( ); ; inline void CStudent: display2( ) cout “num”
13、numdisplay三三; (*p) . display三三;3、通过对象的引用来访问对象成员、通过对象的引用来访问对象成员 CStuent stu1; CStuent &pp=stu1; 三三;声明类类型声明类类型定义对象定义对象使用对象使用对象直接访问直接访问间接访问间接访问简单访问简单访问(三)(三) 对象的存储对象的存储: : 图图1 1 各对象完全独立地安排内存的方案各对象完全独立地安排内存的方案u注意:区别同一个类的各个不同的对象的属性是由数据成员注意:区别同一个类的各个不同的对象的属性是由数据成员决定的,不同对象的数据成员的内容是不一样的;而行为(操决定的,不同对象的数据成员的内
14、容是不一样的;而行为(操作)是用函数来描述的,这些操作的代码对所有对象都是一样作)是用函数来描述的,这些操作的代码对所有对象都是一样的。的。数据区数据区代码区代码区对象对象1 1对象对象数据区数据区代码区代码区对象对象数据区数据区代码区代码区图图2 各对象的代码区共用的方案各对象的代码区共用的方案数据区数据区对象对象1数据区数据区对象对象数据区数据区对象对象公共代码区公共代码区 图图2 仅为每个对象分配一个数据区,而代码区(放所仅为每个对象分配一个数据区,而代码区(放所有成员函数的区域)为各对象共用。有成员函数的区域)为各对象共用。 ?如何确定函数访问的是哪一个对象的数据成员?如何确定函数访问
15、的是哪一个对象的数据成员 this 指针指针物理实现和物理实现和逻辑上关系逻辑上关系节详讲节详讲例例.#include “iostream” using namespace stdclass CStudent float score; public: int num; char sex; public : void fun1( int a); void display( );; void CStudent: display( ) cout sexnumendl; cout “score”scoreb; stud1.score=98.0; stud1.fun1( b); stud1.displa
16、y( ); coutsizeof(CStudent); coutsizeof(stu1); return 0; 类的简单应用类的简单应用. 实际使用中通常利用构实际使用中通常利用构造函数来初始化数据成员造函数来初始化数据成员. ?对象的数据成员如对象的数据成员如何初始化何初始化?类中的私有类中的私有数据成员如数据成员如何赋值何赋值例例#include “iostream” using namespace stdclass CStudent float score;public: int num;private: void fun1( int a); public : void display(
17、int c );; void CStudent: display(int c ) fun1(c); cout “num”numendl; cout “score”scorenum=9011; int b; cinb; (*p1).display( b ); delete p1; return 0; 私有成员函数的使用私有成员函数的使用stud1. display( );消息消息对象对象方法方法4.2 类的默认成员函数及其定义类的默认成员函数及其定义v默认构造函数默认构造函数v默认拷贝构造函数默认拷贝构造函数v默认析构函数默认析构函数v默认赋值运算符函数默认赋值运算符函数v默认取地址运算符函数默
18、认取地址运算符函数 是编译器自动添加的是编译器自动添加的.当功能不满足要求当功能不满足要求时用户可以按要求重新自定义这些函数时用户可以按要求重新自定义这些函数.构造函数和析构函数构造函数和析构函数 C+ 的目标是使得使用类与使用基本的内置类型尽可能相同。的目标是使得使用类与使用基本的内置类型尽可能相同。 即要创建对象,即要创建对象,可以定义类变量,也可以使用可以定义类变量,也可以使用new为类对象分配存储空间。可以将对象作为函数的参数为类对象分配存储空间。可以将对象作为函数的参数和返回值,也可以将一个对象赋给另一个,和返回值,也可以将一个对象赋给另一个, 初始化对象初始化对象-创建对象时对它的
19、数据成员进行初始化。创建对象时对它的数据成员进行初始化。 一种可能的初始化方法:一种可能的初始化方法: 对类的公有数据成员,可象结构体变量一样初始化。对类的公有数据成员,可象结构体变量一样初始化。 (但这违背了类信息隐藏的初衷)(但这违背了类信息隐藏的初衷) Cstudent stu1= 97101,”wangdali”, “男男”; 但往往存在私有数据成员,程序不能直接访问它们,而只能但往往存在私有数据成员,程序不能直接访问它们,而只能通过成员函数来访问这些数据成员,因此要设计合适的成员函通过成员函数来访问这些数据成员,因此要设计合适的成员函数,才能成功的将对象初始化。数,才能成功的将对象初
20、始化。 为此,为此,C+ 提供了特殊的成员函数提供了特殊的成员函数-构造函数构造函数。一、构造函数一、构造函数v功能:构造函数是一种特殊的成员函数,它主要用于对对象成功能:构造函数是一种特殊的成员函数,它主要用于对对象成员进行初始化。员进行初始化。(给具体数值,或给指针成员分配空间等)(给具体数值,或给指针成员分配空间等)v声明和定义构造函数声明和定义构造函数:(具有一些特殊的性质)具有一些特殊的性质)构造函数的名字必须与类名相同。构造函数的名字必须与类名相同。 构造函数可以有任意类型的参数,但不能具有返回值。构造函数可以有任意类型的参数,但不能具有返回值。v构造函数的使用构造函数的使用在创建
21、对象时,系统会自动地调用构造函数。在创建对象时,系统会自动地调用构造函数。 从而保证了先初始化后访问的顺序。从而保证了先初始化后访问的顺序。例如:例如:class cdemo cdemo( ) ;例如:例如:class cdemo cdemo( ); ; cdemo:cdemo( ,.) v例1vclass complexvprivate:vdouble real , imag;vpublic:vcomplex( double r,double i)v real=r; imag=i; vdouble abscomplex三v double t;v t=real*real+imag*imag;v
22、 return sqrt(t);vv;vvoid main三vcomplex A(1.1 , 2.2); /定义类的对象A时调用构造函数complexv complex b(5.6,8.9);vcout” abs of complex A=” A . abscomplex( ) endl;v形参不要与数形参不要与数据成员同名据成员同名v例2 没有参数的构造函数vclass complexvprivate:vdouble real , imag;vpublic:vcomplex( )v real=6; imag=8; vdouble abscomplex三v double t;v t=real*
23、real+imag*imag;v return sqrt(t);vv;vvoid main三vcomplex A;/定义类的对象A时调用构造函数complexvcout” abs of complex A=” A . abscomplex( ) endl;vv例3 用初始化列表对简单的数据成员进行初始化vclass complexvprivate:vdouble real , imag;vpublic:vcomplex(double r,double i) : real(r), imag(i) v ; vdouble abscomplex三v vv;vvoid main三vcomplex A(
24、6.0,8.0) ;/定义类的对象A时调用构造函数complexvcout” abs of complex A=” A . abscomplex( ) endl;v说明:1. 构造函数的名字必须与类名相同,否则将被当作一般的成员函数来处理。一般声明为public 。2. 构造函数也可采用初始化列表对简单的数据成员进行初始化,但数组和指针等成员的初始化应在构造函数体中书写。 初始化列表只能用于类的构造函数。3. 构造函数不能像其它成员函数那样被显式地调用,它是在创建对象的同时系统自动调用一次。4. C+提供两种调用形式: 隐式调用构造函数: complex A(1.1 , 2.2); 显式的调用
25、构造函数: complex A=comples(1.1 , 2.2); 无参构造函数调用形式: complex A;5. 在实际应用中,通常需要给每个类定义构造函数。如果没有给类定义构造函数,则编译系统自动地添加一个默认的构造函数。形如: complex:complex( ) ; /是一个无参空函数。 一旦自定义了构造函数,系统就不再生成默认的构造函数了。class complexprivate:double real , imag;public: void set (double r,double i) real=r;imag=i;double abscomplex三三 double t;
26、t=real*real+imag*imag; return sqrt(t);void main三三complex A;/定义类的对象定义类的对象A时调用默认构造函数时调用默认构造函数complex A.set(1.1,2.2);cout” abs of complex A=” A . abscomplex( ) endl;二、构造函数的重载二、构造函数的重载v一个类中可以定义多个构造函数,以便对类对象提一个类中可以定义多个构造函数,以便对类对象提供不同的初始化方法。供不同的初始化方法。v构造函数的名字相同,参数的个数或类型不同。构造函数的名字相同,参数的个数或类型不同。class comple
27、xprivate:double real , imag;public: complex( ) real=6; imag=8; complex(double r,double i) real=r; imag=I; ; int main三三 complex a , b(1.1,2.2) ; 定义一个对象时,只能执定义一个对象时,只能执行其中一个构造函数。行其中一个构造函数。例:定义了构造函数,但无默认构造函数时例:定义了构造函数,但无默认构造函数时class complexprivate:double real , imag;public: complex(double a ) real= a;
28、imag=a; complex(double r,double i) real=r; imag=I; ; int main三三 complex a(4.0) ,b(1.1,2.2) ; complex c; v为类定义了非默认构造函数后,程序为类定义了非默认构造函数后,程序员一般必须为它提供默认构造函数。这员一般必须为它提供默认构造函数。这样可禁止创建未初始化的对象。样可禁止创建未初始化的对象。三、使用默认参数的构造函数三、使用默认参数的构造函数v对于带参数的构造函数对于带参数的构造函数,在定义对象时必须给构在定义对象时必须给构造函数传递参数,否则构造函数将不被执行造函数传递参数,否则构造函数
29、将不被执行。但但在实际使用中,有些构造函数的参数值通常是不在实际使用中,有些构造函数的参数值通常是不变的,只有在特殊情况下才需要改变它的参数值,变的,只有在特殊情况下才需要改变它的参数值,这时可以将其定义成带默认参数的构造函数这时可以将其定义成带默认参数的构造函数。v在声明构造函数时指定默认参数在声明构造函数时指定默认参数 Complex ( double r=1 , double i=1);相当于多个重载的构造函数。相当于多个重载的构造函数。 重载和默认参数的构重载和默认参数的构造函数不应同时使用,造函数不应同时使用,因容易出现二义性。因容易出现二义性。class complexprivat
30、e:double real , imag;public: complex(double r=1,double i=1);; complex:complex(double r,double i) real=r; imag=I; int main三三 complex a , b(2), c(3,4); 四、析构函数四、析构函数v析构函数也是一种特殊的成员函数析构函数也是一种特殊的成员函数.它执行与构造函数相反的它执行与构造函数相反的操作操作,通常用于执行一些清理任务通常用于执行一些清理任务,如释放分配给对象的内存如释放分配给对象的内存空间等。空间等。v析构函数有以下一些特点析构函数有以下一些特点:
31、析构函数与构造函数名字相同析构函数与构造函数名字相同,但它前面必须加一个波浪号但它前面必须加一个波浪号();析构函数没有参数析构函数没有参数,也没有返回值也没有返回值,而且不能重载而且不能重载,因此在一因此在一个类中只能有一个析构函数个类中只能有一个析构函数;当撤消对象时(对象生命周期结束时)当撤消对象时(对象生命周期结束时),系统会自动地调用析构函系统会自动地调用析构函数。数。例:class complex double real, imag; public: complex(double r=0.0,double i=0.0) coutconstructionendl; real=r;im
32、ag=i; complex三 coutdestructionendl; double abscomplex三 return sqrt(real*real+imag*imag); ; int main三 complex A(1.1 , 2.2); coutabs of complex A=三endl; return 0; construction destruction结果:结果:v析构函数的作用并不是删除对象,而是在撤销对析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作象占用的内存之前完成一些清理工作-释放资源。释放资源。或用户希望在最后一次使用对象之后所执行的任或用
33、户希望在最后一次使用对象之后所执行的任何操作。何操作。v每个类必须有一个析构函数。若没有显式地为一每个类必须有一个析构函数。若没有显式地为一个类定义析构函数,编译系统会自动地添加一个个类定义析构函数,编译系统会自动地添加一个缺省的析构函数。如:缺省的析构函数。如:v complex三三v对于大多数类而言,缺省的析构函数已经足够了。对于大多数类而言,缺省的析构函数已经足够了。但是,如果在一个对象完成其操作之前需要做一但是,如果在一个对象完成其操作之前需要做一些内部处理,则应该显式地定义析构函数,例如:些内部处理,则应该显式地定义析构函数,例如:class dataprivate: int *p;
34、public:data(int a) p=new int; *p=a; data三 delete p; ; int main三三 data x(6); return 0;例例1:释放内存释放内存class string_dataprivate: char *str;publie:string_data(char *s) str=new charstrlen(s)+1; strcpy(str , s);string_data三 delete str; /; int main三三 string_data x(“abc”); / return 0;例例2:释放内存:释放内存同一类存储类别的对象的构造
35、和析构的执行顺序class XYZ;int main三XYZ A,B; 对象对象A A对象对象B B构构造造析析构构调用构造函数和析构函数的顺序调用构造函数和析构函数的顺序先构造的后析构,后构造的先析构先构造的后析构,后构造的先析构 对象的存储类别不同,生命周期不同对象的存储类别不同,生命周期不同v全局对象:在主函数之前构造,主函数结束或调用全局对象:在主函数之前构造,主函数结束或调用exit(0)时,析构。时,析构。v局部自动对象局部自动对象:函数调用,建立对象时构造,函数结函数调用,建立对象时构造,函数结束时析构。多次调用函数,就多次构造和析构。束时析构。多次调用函数,就多次构造和析构。v
36、局部静态对象:程序第一次调用函数时构造,主函局部静态对象:程序第一次调用函数时构造,主函数结束或调用数结束或调用exit(0)时,析构。其间,调用函数不时,析构。其间,调用函数不构造也不析构。构造也不析构。void fun三static cstudent b; cstudent c;main( ) coutbeginendl; fun三; cstudent *p1; p1=new cstudent; delete p1; fun三;例:构造和析构顺序例:构造和析构顺序 #include iostreamusing namespace std;class cstudentint num; pub
37、lic: cstudent 三三; cstudent三三 ; stu1;cstudent:cstudent三三 cout构造函数构造函数a=ma;this-b=mb;v我们可以直接显式的使用我们可以直接显式的使用this 指针指针 例例 4.11 v构造函数等特殊成员函数中也有构造函数等特殊成员函数中也有this指针。指针。v成员函数内部访问其他成员函数,成员函数内部访问其他成员函数,this指针将被指针将被逐级传递下去。逐级传递下去。v this 指针是指针是const 指针,即编译器规定不允许在指针,即编译器规定不允许在程序中修改它的值。程序中修改它的值。当形式参数与数据成员同名时,需要加
38、当形式参数与数据成员同名时,需要加thisthis:class ABCclass ABCint x;int x;public:public:void set(int x)void set(int x) this-x = x; / this-x = x; /或或( (* *this).x=x;this).x=x;void outvoid out三三 coutx; coutx; ;int mainint main三三 ABC p;ABC p;p.set(5);p.set(5);三三; ;return 0;return 0; C+C+对变量的检查顺序:局部变量、类的数据成员、全局变量。对变量的检查顺
39、序:局部变量、类的数据成员、全局变量。4.3.2 对象的访问方法与规则对象的访问方法与规则对象的访问:指对对象成员的访问。对象的访问:指对对象成员的访问。1.访问方法:简单访问、直接访问、间接访问。访问方法:简单访问、直接访问、间接访问。 2.访问规则:根据访问位置制订不同访问规则内部访问及规则:在成员函数里面对本类对象的 访问当前对象的访问:可直接、间接、简单本类其他对象的访问:可直接、间接内部访问可方位对象的所有成员。外部访问:在全局函数里访问任何类的对象成员。或在某类的成员函数里访问其它类的对象的成员。间接、直接只能访问公有成员v例:例:class demo int a; fun1( )
40、; public: demo(int c); fun2 (demo b ); ;demo:demo(int c) a =c;demo:fun1( ) coutafun(d1); d1.a=9; /错误错误4.3.3 对象的使用对象的使用v point p1 ,p2; p2=p1; /对象的赋值对象的赋值 point p3(p1), p4=p1; /对象拷贝对象拷贝 point & p5=p1; /引用引用 point *p =&p1; /指针指针v通过函数参数传递对象通过函数参数传递对象函数形参为普通对象函数形参为普通对象函数形参为对象指针函数形参为对象指针函数形参为对象的引用函数形参为对象的
41、引用见书上例,见书上例,4.16 ,4.17 v函数返回对象函数返回对象函数返回普通对象函数返回普通对象函数返回对象指针函数返回对象指针 :被取地址对象必须要有:被取地址对象必须要有较长的生存期。较长的生存期。函数返回对象的引用:被返回对象必须要有函数返回对象的引用:被返回对象必须要有较长的生存期。较长的生存期。见书上例,见书上例,4.19 ,4.20 4.3.4 对象数组对象数组v指所有数组元素都是对象的数组。指所有数组元素都是对象的数组。 若一个类有若干个对象,我们把这一系列的对若一个类有若干个对象,我们把这一系列的对象用一个数组来存放。象用一个数组来存放。 v建立对象数组时,每一个元素都
42、要调用构造函建立对象数组时,每一个元素都要调用构造函数初始化。数初始化。 静态创建数组:要提供合适的初始化实参。静态创建数组:要提供合适的初始化实参。 动态创建类对象数组。动态创建类对象数组。v数组元素的访问方法:下标法、地址法、指针数组元素的访问方法:下标法、地址法、指针法。法。指向对象的指针指向对象的指针注意初始化对象数组的方法注意初始化对象数组的方法class complex private: double real , imag; public: complex(double a ) real= a; imag=a; complex(double r, double i) real=r
43、; imag=i; complex 三三 real=imag=0.0; double abscomplex三三 double t; t=real*real+imag*imag; return sqrt(t); ; 例:定义并初始化对象数组例:定义并初始化对象数组 complex demo15;complex demo35=1,4,2,3,6;complex demo25= complex(1), complex三三, complex(1.1,2.2) ; cout静态成员函数名三;静态成员函数名三; stud1.average三三; pstud1-average三三;v使用静态成员函数的另一个
44、原因是:可以用它在使用静态成员函数的另一个原因是:可以用它在建立任何对象之前处理静态数据成员,这是普通建立任何对象之前处理静态数据成员,这是普通成员函数不能实现的功能。成员函数不能实现的功能。v比全局变量要安全。比全局变量要安全。例:见书例:见书138页例页例4.5 数据的保护数据的保护v有些数据,可以在不同场合通过不同途径访问,为有些数据,可以在不同场合通过不同途径访问,为了保证数据的安全,即不被任意修改,可以使用了保证数据的安全,即不被任意修改,可以使用const 来对其属性进行限定。来对其属性进行限定。v有关类的数据保护的限定的几种形式:有关类的数据保护的限定的几种形式:v常成员常成员v
45、常对象常对象v对象的常引用对象的常引用v指向对象的常指针指向对象的常指针指向常对象的指针变量指向常对象的指针变量和对象有关的函数参数和对象有关的函数参数保护对象内容不被修改保护对象内容不被修改(一)常成员(一)常成员1、常数据成员、常数据成员v用用const 来声明常数据成员。其值不能改变。不能来声明常数据成员。其值不能改变。不能被赋值。被赋值。v只能通过构造函数的参数初始化表对常数据成员进只能通过构造函数的参数初始化表对常数据成员进行初始化。行初始化。例:例:class Time const int hour; int sec; public: Time (int h) :hour(h) s
46、ec=0; Time( int h) hour =h; sec=0;void f三三 couthour; hour=9; sec=30; ; int main( ) Time a1(8), a2(9); a1.f三三; a2.f三三; return 0 2、常成员函数、常成员函数v格式:格式: 返回类型返回类型 成员函数名(形参)成员函数名(形参)const 声明和定义函数时都要加声明和定义函数时都要加const ,调用时不需加。调用时不需加。v功能特点:功能特点:只能读本类中的数据成员而不能修改它们。只能读本类中的数据成员而不能修改它们。除非是可变的数据成员:除非是可变的数据成员:mutab
47、le int count; ,可用常,可用常成员函数来修改它的值。成员函数来修改它的值。常成员函数不能调用非常成员函数。(防止间接修改)常成员函数不能调用非常成员函数。(防止间接修改) 常成员是从类的角度,在类内声明常成员是从类的角度,在类内声明成员的成员的const属性属性(二)常对象(二)常对象v定义对象时指定对象为常对象。定义对象时指定对象为常对象。v格式:格式: 类名类名 const 对象名对象名 (实参表列)(实参表列); const 类名类名 对象名对象名 (实参表列)(实参表列);v不允许修改常对象中的数据成员的值。不允许修改常对象中的数据成员的值。 常对象的数据成员为常变量且必
48、须要有初值。常对象的数据成员为常变量且必须要有初值。(由构造函数初始化)由构造函数初始化)v外界只能调用常对象的常成员函数(除了由系统自动调用的隐式的外界只能调用常对象的常成员函数(除了由系统自动调用的隐式的构造函数和析构函数),以防止修改对象中的数据成员的值。构造函数和析构函数),以防止修改对象中的数据成员的值。 因常成员函数可以引用数据成员,但不会改变数据成员的值。因常成员函数可以引用数据成员,但不会改变数据成员的值。可变的数据成员:可变的数据成员:mutable int count; 可用常成员函数来修改它的值。可用常成员函数来修改它的值。例:例:class d int i; publi
49、c: int a; d( )i=0;a=9; s( )i=6; f( ) const; ;d :f三三 constint q; q=i; coutq; int main( )const d d1;d1.f( );coutd1.a; d1.s( ); d1.a=4; d d2; d2.f三三;coutd2.a; d2.s三三;d2.a=4;return 0;(三)对象的常引用(三)对象的常引用v格式:格式:const 类名类名 &引用名引用名=对象;对象;v不能通过该引用改变对象。不能通过该引用改变对象。v常用于函数形参,和指向常对象的指针变量一样,常用于函数形参,和指向常对象的指针变量一样,使
50、函数执行过程中,不能通过形参改变实参的值。使函数执行过程中,不能通过形参改变实参的值。 常引用、指向常对象的指针常引用、指向常对象的指针和常成员函数可保证调用对和常成员函数可保证调用对象不被修改象不被修改(四)、指向常对象的指针变量(四)、指向常对象的指针变量v指向常对象的指针变量即可指向常对象,也可指指向常对象的指针变量即可指向常对象,也可指向非常对象。不能通过该指针改变对象。向非常对象。不能通过该指针改变对象。v只能用指向常对象的指针变量指向常对象。只能用指向常对象的指针变量指向常对象。v该指针变量本身可以改变。该指针变量本身可以改变。v常用于函数形参,目的是保护形参指针所指向的常用于函数
51、形参,目的是保护形参指针所指向的对象,使它在函数执行过程中不被修改。即只想对象,使它在函数执行过程中不被修改。即只想在函数中引用该对象,而不想改变它。在函数中引用该对象,而不想改变它。 例:例:Time t1(10,12,15); const Time *p1=&t1; t1.hour=18; (*p1).hour=18;例:例:const Time t2(10,12,15); const Time *p2=&t2; t2.hour=18; (*p2).hour=18; 成员函数数据成员非const 成员函数const 成员函数非const 数据成员可以使用,可以改变值 可以使用,不可以改变值
52、const 数据成员可以使用,不可以改变值 可以使用,不可以改变值 |常对象和常成员对比常对象和常成员对比 常对象是在类外定义对象时,定义为常对象的。当然也常对象是在类外定义对象时,定义为常对象的。当然也可定义该类的非常对象。可定义该类的非常对象。 无论类内对成员如何声明,该常对象的数据成员全转变无论类内对成员如何声明,该常对象的数据成员全转变为常变量,函数成员的属性不变。为常变量,函数成员的属性不变。 若想引用常对象的数据成员,在类声明时必须声明有若想引用常对象的数据成员,在类声明时必须声明有常成员函数。常成员函数。 具有常成员的类即可定义非常对象也可定义常对象。具有常成员的类即可定义非常对
53、象也可定义常对象。 完全不具备常成员的类即可定义非常对象也可定义常对完全不具备常成员的类即可定义非常对象也可定义常对象,但此时常对象没法使用。象,但此时常对象没法使用。 常对象非const 成员函数const 成员函数 const对象的数据成员外部不能调用可使用,可改非const数据成员的值外部可以调用,可使用,不可改变值v如何利用常对象和常成员如何利用常对象和常成员v当类中只有部分数据成员的值允许改变时,可当类中只有部分数据成员的值允许改变时,可将这部分数据成员声明为将这部分数据成员声明为const 。v若所有数据成员的值都不许改变,可将所有数若所有数据成员的值都不许改变,可将所有数据成员声
54、明为据成员声明为const,或将对象声明为常对象。或将对象声明为常对象。通过常成员函数来引用常对象中数据成员。通过常成员函数来引用常对象中数据成员。(四)指向对象的常指针(四)指向对象的常指针v格式:类名格式:类名 * const 指针变量名指针变量名 =对象地址;对象地址;v指针值始终保持为其初始化值,不能改变,即其指针值始终保持为其初始化值,不能改变,即其指向始终不变。指向始终不变。v可将一个指针变量固定的和一个对象相联系。可将一个指针变量固定的和一个对象相联系。v往往用常指针作为函数的形参,目的是不允许函往往用常指针作为函数的形参,目的是不允许函数执行中改变指针变量的值,使其始终指向原来
55、数执行中改变指针变量的值,使其始终指向原来的对象。的对象。v例:例:Time t1(10,12,15),t2; Time *const ptr1=&t1;v对所指对象的使用没有限制。对所指对象的使用没有限制。 (五)指向常对象的指针变量(五)指向常对象的指针变量 1、指向常变量的指针变量、指向常变量的指针变量v格式:格式: const 类型名类型名 *指针变量名;指针变量名;v可用其指向:常变量可用其指向:常变量 非常变量非常变量v不能通过该指针改变其所指变量的值。不能通过该指针改变其所指变量的值。v该指针可以指向不同的变量。该指针可以指向不同的变量。v例:例: int a; const in
56、t b=7; const int *p;p=&a; *p=9; p=&b; *p=8; int c; c=*p; v当用指针变量作函数形参时,形参和实参的对应关系当用指针变量作函数形参时,形参和实参的对应关系 形参形参 实参实参 指向非指向非const 型变量的指针型变量的指针 非非const变量的地址变量的地址 指向指向const型变量的指针型变量的指针 const变量的地址变量的地址 非非const变量的地址变量的地址函数中不能通过形参改变其所指实参的值函数中不能通过形参改变其所指实参的值 例:例:void fun1( char *p); char a=q; fun1 (&a); void
57、 fun1(char *p) *p=w;例:例:void fun2(const char *p); char a=t; fun2 (&a); const char b=r; fun2(&b); void fun2 (const char *p) cout*p; 2、指向常对象的指针变量、指向常对象的指针变量v只能用指向常对象的指针变量指向常对象。只能用指向常对象的指针变量指向常对象。v指向常对象的指针变量即可指向常对象,也可指指向常对象的指针变量即可指向常对象,也可指向非常对象。不能通过该指针改变对象。向非常对象。不能通过该指针改变对象。v该指针变量本身可以改变。该指针变量本身可以改变。v常用
58、于函数形参,目的是保护形参指针所指向的常用于函数形参,目的是保护形参指针所指向的对象,使它在函数执行过程中不被修改。即只想对象,使它在函数执行过程中不被修改。即只想在函数中引用该对象,而不想改变它。在函数中引用该对象,而不想改变它。 例:例:Time t1(10,12,15); const Time *p1=&t1; t1.hour=18; (*p1).hour=18;例:例:const Time t2(10,12,15); const Time *p2=&t2; t2.hour=18; (*p2).hour=18; fun1 (ABC p) fun2 (ABC *p) fun3 (const
59、 ABC *P) /指向常对象的指针指向常对象的指针 fun4 (ABC *const p) /常指针常指针 fun5(ABC &p) /引用引用 fun6 (const ABC &p)( /常引用常引用int main三三 ABC p3; fun1(p3);/以以“值方式值方式”传递对象,传递对象,p3不被修改不被修改 fun2(&p3);/以以“指针方式指针方式”传递对象,传递对象,p3可被修改可被修改 fun3(&p3);/以以“指常指针方式指常指针方式”传递对象,传递对象,p3不可被修改不可被修改 fun4(&p3);/以以“常指针方式常指针方式”传递对象,传递对象,p3可被修改可被修
60、改 fun5(p3); /以以“引用方式引用方式”传递对象,传递对象,p3可被修改可被修改 fun6(p3); /以以“常引用方式常引用方式”传递对象,传递对象,p3不可被修改不可被修改向函数传递对象向函数传递对象 (六)、指向对象成员的指针(六)、指向对象成员的指针对象成员的指针对象成员的指针指向对象成员的指针变量指向对象成员的指针变量 1、数据成员(公有)、数据成员(公有) 例:例:double *p1=&; *p1=6; 2、函数成员、函数成员 (公有)(公有) 格式:数据类型名格式:数据类型名 (类名(类名: *指针变量名)指针变量名)(参数列表参数列表); 函数返回值类型函数返回值类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 基于智能精准教研的教师专业素养培养策略研究教学研究课题报告
- 26年老年患者心理需求宣教
- 26年基础护理技能全民福寿课件
- 26年老年护理营养要点总结课件
- 26年半失能护理讲解课件
- 2026年湖南省邵阳县第一中学高三第一次联合调研考试化学试题含解析
- 陕西省武功县长宁高级中学2026届5月高三压轴卷化学试题试卷含解析
- 江西省赣州市四所重点中学2026届高三学业水平考试试题化学试题含解析
- 肺癌患者下呼吸道感染特征及多因素解析:临床与防治视角
- 肺康颗粒对COPD稳定期肺肾亏虚证患者生存质量影响的临床探究
- 统编(2024)八年级历史下册第17课推进国防军队建设和外交工作【课件】
- 2026年灭火器年检与充装更换管理
- (三模)济南市2026届高三5月针对性训练英语试卷(含答案)
- 2026重庆市航空应急救援总队航空应急救援专职人员招聘34人笔试模拟试题及答案解析
- 《电力重大事故隐患判定标准及治理监督管理规定》深度解读
- 2026年上海市金山区初三二模语文试卷
- 2026庐山云雾茶产业集团有限公司社会招聘工作人员16人备考题库及答案详解(新)
- 第二单元《第2课 律动青春》教学设计- 人教版(2024)初中美术七年级下册
- 2026年人工智能训练师(五级)综合技能真题题库
- 2026山东省科创集团有限公司权属企业招聘13人笔试历年典型考点题库附带答案详解
- 2026中医医师定期考核题库(附答案)临床真题(附答案)
评论
0/150
提交评论