《C面向对象编程》PPT课件.ppt_第1页
《C面向对象编程》PPT课件.ppt_第2页
《C面向对象编程》PPT课件.ppt_第3页
《C面向对象编程》PPT课件.ppt_第4页
《C面向对象编程》PPT课件.ppt_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

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

文档简介

C+面向对象程序设计,主要内容,类 对象 类的封装性与信息隐藏 构造函数与析构函数 类的静态成员 基类和派生类 虚函数和多态,对象和类,属性: 年龄; 性别; 身高; 体重; 动作: 跑; 跳; 说话;,person,面向对象编程的程序基本单位是类 类是数据和操作数据的函数的封装体 类的对象使用自己的方法完成对数据的操作 类可以隐藏数据和操作细节 对象通过类接口与外部通信,1.1 类,struct Time int hour; / 0-23 int minute; / 0-59 int second; / 0-59 ;,结构 Vs 类,#include struct Time int hour; int minute; int sec; ;,int main( ) Time t1; cint1.hourt1.minute t1.sec; coutt2.hourt2.minutet2.sec; coutt2.hour:t2.minute :t2.secendl; return 0; ,set_time(t1);,set_time(t2);,show_time( t1 );,show_time( t2 );,void set_time(Time,void show_time(Time,结构 Vs 类,#include struct Time int hour; int minute; int sec; ; void set_time(Time ,int main( ) Time t1; set_time(t1); show_time(t1); Time t2; set_time(t2); show_time(t2); return 0; ,结构 Vs 类,class Time private : 关于时间的数据; public : 读取时间值 ; 调整时间值 ; ;,类是数据和 操作数据的函数的封装,结构 Vs 类,class Time private : int hour; int minute; int second; public : 读取时间值 ; 调整时间值 ; ;,public : void set( int, int, int) ; void get( );,对象使用自己的方法 对数据操作,结构 Vs 类,对象通过类接口与外部通信,class Time private : int hour; int minute; int second; public : 读取时间值 ; 调整时间值 ; ;,public : void set( int, int, int) ; void get( );,结构 Vs 类,改用含成员函数的类来处理 #include class Time public: void set_time( ); void show_time( ); private: int hour; int minute; int sec; ;,int main( ) Time t1; t1.set_time( ); t1.show_time( ); Time t2; t2.set_time( ); t2.show_time( ); return 0; ,结构 Vs 类,void Timeset_time( ) cinhour; cinminute; cinsec; void Timeshow_time( ) couthour: minute: secendl; ,class Time public: void set_time( ) cinhourminutesec; void show_time( ) couthour: minute: secendl; private: int hour; int minute; int sec; ;,结构 Vs 类,1。类的声明,面向对象编程的基础是把自己的数据类型定义为类,类是用户定义的数据类型。 定义一个类后,就可以用类名声明类类型的变量,即将类实例化为不同的对象; C+中用关键字class定义包含数据成员和成员函数的类型。类使程序员可以构造对象的属性和行为或操作。,1。声明类类型,类是一种用户自定义的数据类型,它的一般定义格式如下: class 类名 private: 私有数据成员和成员函数; protected: 保护数据成员和成员函数; public: 公有数据成员和成员函数; ; 各个成员函数的实现;,1 class Time 2 public: 3 void setTime( int, int, int); 4 void printMilitary(); 5 void printStandard(); 6 private: 7 int hour; / 0-23 8 int minute; / 0-59 9 int second; / 0-59 10 ;,定义类类型,/分号不能忽略!,1。声明类类型,1 class Time 2 public: 3 Time( ); 4 void setTime( int, int, int); 5 void printMilitary(); 6 void printStandard(); 7 private: 8 int hour; / 0-23 9 int minute; / 0-59 10 int second; / 0-59 11 ;,1。声明类类型,公有成员 成员函数,私有成员 数据成员,/成员访问说明符,/成员访问说明符,2。访问控制,private声明的数据和函数不能在类以外访问 public声明的数据和函数可以在类以外访问 缺省默认为private访问类型的,类,数据和函数,私有,公有,无法从类的外部访问,可以从类的外部访问,数据和函数,2。访问控制,成员访问说明符 公有 public: 说明为公有的成员可以被程序中的任何代码访问; 私有 private: 说明为私有的成员只能被类本身的成员函数及友元 类的成员函数访问,默认类的对象的成员是私有; 保护 protected: 除了类本身的成员函数和说明为友元类的成员函数可以访问保护成员外,该类的派生类的成员也可以访问。,class Tdate private: int month; int day; int year; public: void Set(int m, int d, int y ) ; bool IsLeapYear( ); void Print(); ;,练习:声明日期类,类由成员构成: 数据成员描述对象的属性 成员函数描述对象的方法,3。成员函数,成员函数为描述对象的方法 一般定义为公用的 类定义中的成员函数被默认创建为内联函数 可在类的外部定义成员函数,在类的外部定义成员函数的语法: 返回类型 类名:成员函数名(参数列表) 函数定义体 ,双冒号称为域名解析分解符,class Tdate public: void Set(int m, int d, int y ) ; bool IsLeapYear(); void Print( ); private: int month; int day; int year; ; void Tdate:Set(int m, int d, int y ) month = m ; day = d ; year = y ; bool Tdate: IsLeapYear() return ( year%4 = 0 ,类的声明,类的实现,在类外定义 成员函数,class Tdate public: void Set(int m, int d, int y ) month = m ; day = d ; year = y ; int IsLeapYear() return ( year%4 = 0 ,练习:声明日期类,类中定义成员函数 内联函数处理,1.2 对象,1。实例化(Initializing) 指创建一个类的实例; 对象是类的实例(即是一个具体的例子)。 对象的定义 (1)先声明类类型,后定义对象,class Tdate ; Tdate d1,d2; / 直接用类名定义对象。,(2) 在声明类类型的同时定义对象,class Tdate public: void Set(int m, int d, int y ) int IsLeapYear() void Print( ) private: int month; int day; int year; d1, d2;,1.2 对象,类说明的一般形式为: class 类名 public: 公有段数据成员和成员函数 ; protected: 保护段数据成员和成员函数 ; private: 私有数据成员和成员函数 ; ;,注意: 允许已定义类名出现在类的说明中,例: class X ; class Y X dataMember ; ;,/ 声明一个类类型数据成员,2. 对象成员的引用 一个对象的成员就是该对象的类所定义的成员。一般对象的成员表示如下: 数据成员 对象名. 成员名 成员函数 对象名. 成员名(参数表) “.”运算符的功能是表示对象的成员。,或 对象指针名-成员名,对象指针名-成员名(参数表),1.2 对象,调用成员函数,对象名称 . 成员函数 对象指针名-成员函数 或 (*对象指针名).成员函数,点运算符、类成员访问运算符,成员函数 vs. 一般函数 都有函数体,返回值和函数类型。 成员函数属于一个类的成员,出现在类体中 成员访问说明符限制private、public 注意调用它的权限以及它的作用域 成员函数必须由对象句柄调用 和数据成员封装成一体,1.2 对象,2。访问对象中的成员可以有3种方法: 通过对象名和成员运算符访问对象中的成员; 通过指向对象的指针访问对象中的成员; 通过对象的引用变量访问对象中的成员。,class A private : / / private说明符在首次出现时可以省略 int m_a; public: / / 切换到public说明符,以下就是共有成员 int m_b; void print( )coutabc; protected: int m_c; / / 该成员是保护的 ,1.2 对象,main() A a; a.m_a; a.m_c; a.m_b; a.print(); ,用类去定义对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间。,成员的存储方式,coutsizeof(Tdate)endl;,类中被操作的数据是私有的,实现的细节对用户是隐蔽的,这种实现称为私有实现。 在声明了一个类以后,用户主要是通过调用公用的成员函数来实现类提供的功能。因此,公用成员函数是用户使用类的公用接口,或者说是类的对外接口。 软件工程的一个最基本的原则就是将接口与实现分离,信息隐蔽是软件工程中一个非常重要的概念。,1.3 类的封装性和信息隐蔽,1. 公用接口与私有实现的分离,#include class Date public: void Set(int m,int d,int y) month=m; day=d; year=y; bool IsLeapYear( ) return (year%4=0,void main( ) Date a; a.Set(2,4,1998); a.Print( ); ,/设置日期,/判断闰年,/输出日期值,在面向对象的程序开发中,一般做法是将类的声明放在指定的头文件中,用户如果想用该类,只要把有关的头文件包含进来即可,不必在程序中重复书写类的声明,以减少工作量,节省篇幅,提高编程的效率。 由于在头文件中包含了类的声明,因此在程序中就可以用该类来定义对象。由于在类体中包含了对成员函数的声明,在程序中就可以调用这些对象的公用成员函数。为了实现上一节所叙述的信息隐蔽,对类成员函数的定义一般不放在头文件中,而另外放在一个文件中。,2. 类声明和成员函数定义的分离,/ date.h class Date public: void Set(int m,int d,int y); int IsLeapYear( ); void Print( ); private: int month; int day; int year; ;,自定义类库头文件.h, 包括设计的类的定义,即类的外部接口。 将类声明放在使用该类的任何客户的头文件中, 这就形成类的Public接口 (并向客户提供调用类成员函数所需的函数原型)。,/date.cpp # include # include“date.h” void Date :Set(int m,int d,int y) month=m; day=d; year=y; int Date : IsLeapYear( ) return (year%4=0 ,用户自定义类库的内部实现源文件, 包括相关头文件和类中成员函数的定义。 这就形成类的实现方法。,类的 内部实现,# include # include“date.h” void main( ) Date a; a.Set(2,4,1998); a.Print( ); ,唯一包含主函数的源文件, 包括所有相关头文件及main()。,/student.h class Student public: void display( ); private: int num; char name20; char sex; ;,/student.cpp #include #include student.h void Studentdisplay( ) coutnum:numendl; coutname:nameendl; coutsex:sexendl; ,/main.cpp 主函数模块 #include #include student.h /将类声明头文件包含进来 int main( ) Student stud; /定义对象 stud.display( ); /执行stud对象的display函数 return 0; ,类库有两种: C+编译系统提供的标准类库; 用户根据自己的需要做成的用户类库,提供给自己和自己授权的人使用,这称为自定义类库。 类库两个组成部分: 类声明头文件(*.h); 已经过编译的成员函数的定义,它是目标文件(*.dll)。 用户只需把类库装入到自己的计算机系统中(一般装到C+编译系统所在的子目录下),并在程序中用#include命令行将有关的类声明的头文件包含到程序中,就可以使用这些类和其中的成员函数,顺利地运行程序。,1.4 构造函数和析构函数,构造函数(constructor) 作用: 为对象分配空间;对数据成员赋初值;请求其他资源 调用: 生成类对象时,其成员可用类的构造函数初始化。 当类对象进入其作用域时,自动调用构造函数。 特点: 构造函数是与类同名的成员函数 可有任意类型的参数,但没有返回类型,析构函数(destructor) 用于取消对象的成员函数 作用: 进行清除对象,释放内存等 调用: 当一个对象生命期结束时,系统自动调用析构函数 没有定义析构函数时,系统提供缺省版本的析构函数 特点: 析构函数名为: 类名 没有参数,也没有返回类型,1.4 构造函数和析构函数,class Time public: Time( );/无参构造函数 void set_time(int,int,int ); void show_time( ); private: int hour; int min; int sec; ; ,1. 构造函数,初始化类对象 的数据成员, 在生成这个类的对象时自动调用 。,#include int main( ) Time t1; t1.set_time( ); t1.show_time( ); ,1.构造函数,默认构造函数 自定义构造函数 带默认参数的构造函数 重载构造函数,1.构造函数,默认构造函数 如果一个类没有定义构造函数,编译器会自动生成一个不带参数的默认构造函数,其格式如下: :() ,1.构造函数,自定义构造函数 自动初始化成员变量,Time: Time( ) / 无参构造函数 hour=0;min=0;sec=0 ; ,带参数的构造函数 带参数的构造函数可以在创建对象时,用具体数值初始化数据成员和各种数据元素。可方便实现对不同对象进行初始化。 构造函数的首部: 构造函数名(形参列表); 定义对象的一般格式: 类名 对象名(实参列表),1.构造函数,1.构造函数,带参数的构造函数,class Time public: Time(int h, int m, int s ) hour=h;min=m;sec=s ; private: int hour; int min; int sec; ;,Time(int h, int m, int s ) hour=h;min=m;sec=s ; ,#include int main( ) Time t2(8,15,16); t2.show_time( ); return 0; ,用参数初始化列表对数据成员初始化,1.构造函数,默认构造函数 自定义构造函数 重载构造函数 构造函数可以像普通函数一样被重载 在类中可以定义多个构造函数,以便对类对象提供不同的初始化方法。 根据说明中的参数个数和类型选择合适的构造函数。,1.构造函数,重载构造函数,class Time public: Time(): hour(0),min(0),sec(0) Time(int h, int m, int s ) hour=h;min=m;sec=s ; private: int hour; int min; int sec; ;,#include int main( ) Time t1; t1.set_time( ); t1.show_time( ); Time t2(8,15,16); t2.show_time( ); return 0; ,Time(int h 0, int m0, int s0 ) hour=h;min=m;sec=s ; ,#include int main( ) Time t1, t2(2), t3(21, 34), t4(12, 25, 42), t5(27, 74, 99); return 0; ,class Time public: Time(int h=0, int m=0, int s=0): hour(h),min(m),sec(s) void set_time( ); void show_time( ); private: int hour; int min; int sec; ; ,1.构造函数,2 析构函数(destructor) 构造函数的反函数,析构函数是用于取消对象成员函数,当一个对象生命期结束时,系统自动调用析构函数。 析构函数名字为符号“”加类名; 析构函数没有参数和返回值。 一个类中只可能定义一个析构函数, 析构函数不能重载。 析构函数的作用 进行清除对象,释放内存等;,如果一个类没有定义析构函数,编译器会自动生成一个默认析构函数,其格式如下: 类名: 默认析构函数名() 默认析构函数是一个空函数。,2 析构函数(destructor),class Time public: Time(); Time( int , int , int ); Time(); private: int hour; int min; int sec;,3. 构造函数与析构函数的调用,构造函数与析构函数自动调用 (1) 一个对象当其结束生命周期时 ; (2) 使用new运算符创建的对象, 在使用delete运算符释放该对象时; 不调用delete将不会析构,#include #include class Student private: int num; char* name ; char sex; public: Student(int n, char* nam , char s ) :num(n),sex(s) name = new char10; strcpy(name,nam); Student( ) delete name; void display( ); ;,关键字 static 可以用于说明一个类的成员 静态成员提供了一个同类对象的共享机制 把一个类的成员说明为 static 时,这个类无论有多 少个对象被 创建,这些对象共享这个 static 成员 静态成员属于类,它不是对象成员,1.5 静态成员,类、对象和内存,对象1,对象2,对象3,数据1,数据2,数据1,数据2,数据1,数据2,函数1,函数2,类、对象和内存,对象1,对象2,对象3,数据1,数据2,数据1,数据2,数据1,数据2,函数1,函数2,静态成员,数据3,函数3,公有成员,class X char ch ; static int s ; . ; int X : s = 0 ; object A , B , C , D ;,X B ; char ch ;,X C ; char ch ;,X D ; char ch ;,X A ; char ch ;,static int s ;,1.5 静态成员,1. 静态类成员数据,静态成员是指声明为static的类成员在类的范围内所有对象共享某个数据。 类定义中的静态成员生命期与整个程序相同 静态成员变量在类的内部声明,类的外部定义 静态数据成员不从属于任何一个具体对象,所以必须对它初始化,且对它的初始化不能在构造函数中进行。,1。静态类成员数据,静态数据成员的使用方法如下: 1)静态数据成员的定义与一般数据成员相似,但前面要加上static关键词。 2)静态数据成员的初始化与一般数据成员不同,静态数据成员初始化的格式如下: :=; 不能省,私有也要初始化。 3)在引用静态数据成员时采用格式: : . ,静态数据成员 vs 全局变量 有了静态数据成员,各对象之间的数据有了沟通的渠道,实现数据共享 。 全局变量破坏了封装的原则,不符合面向对象程序的要求。 公用静态数据成员与全局变量的作用域不同 静态数据成员的作用域只限于定义该类的作用域内,1。静态类成员数据,静态成员函数数冠以关键字static 静态成员函数提供不依赖于类数据结构的共同操作 在类外调用静态成员函数用 “类名 : ”作限定词, 或通过对象调用.,2 静态成员函数,2.静态成员函数,可由任意访问权限许可的函数访问。 和一般成员函数类似,静态成员函数也有访问限制, 私有静态成员函数不能由外界访问。 只能访问静态数据成员、静态成员函数和类以外的函数和数据;不能访问类中的非静态数据成员,静态成员函数 没有this指针,2.静态成员函数,静态成员函数的作用: 能处理静态数据成员 静态成员函数vs非静态成员函数 根本区别是: 非静态成员函数有this指针, 静态成员函数没有this指针。由此决定了静态成员函数不能访问本类中的非静态成员。,1.6 基类和派生类,一个基类可以是另一个基类的派生类,这样便形成了复杂的继承结构,出现了类的层次。一个基类派生出一个派生类,它又做另一个派生类的基类,则原来的基类为该派生类的间接基类。 1. 派生类是基类的特殊化。 2. 派生类是基类定义的延续。 3. 基类是派生类的公有特性。 派生类将其本身与基类区别开来的方法是添加数据成员和成员函数。,类继承关系的语法形式 class 派生类名 : 基类名表 数据成员和成员函数声明 ;,基类名表 构成 访问控制 基类名1 , 访问控制 基类名n,class Student / ; class CollegeStudent : public Student / ; class GraduateSudent: private collegeStudent / . ;,访问控制 表示派生类对基类的继承方式,,定义派生类,定义派生类,继承方式与可访问性,访问控制符,自己所属类 可以访问,派生类 可以访问,类之外的对象可以访问,public 是 是 是 protected 是 是 否 private 是 否 否,派生类定义了与基类同名的成员,在派生类中访问同名成员时屏蔽了基类的同名成员 在派生类中使用基类的同名成员, 显式使用类名限定符: 类名 : 成员,重名成员,联编是指一个程序模块、代码之间互相关联的过程。 静态联编:程序的匹配、连接在编译阶段,也称为早期匹配。重载函数使用静态联编。 动态联编:指程序联编推迟到运行时进行,所以又称为晚期联编。 多态:采用动态联编技术实现向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。,1.7 虚函数与多态性,基类指针和派生类指针 基类对象和派生类对象 4种可能匹配: 直接用基类指针引用基类对象; 直接用派生类指针引用派生类对象; 用基类指针引用一个派生类对象; 用派生类指针引用一个基类对象。,1. 类指针的关系,例如: A * p ; / 指向类型 A 的对象的指针 A A_obj ; / 类型 A 的对象 B B_obj ; / 类型 B 的对象 p = / p 指向类型 B 的对象,它是 A 的派生类,利用 p,可以通过 B_obj 访问所有从 A_obj 继承的元素 , 但不能用 p访问 B_obj 自身特定的元素 (除非显式类型转换),2. 基类指针引用派生类对象,class A_class char name20 ; public : void put_name( char * s ) strcpy( name, s ) ; void show_name() cout name “n“ ; ; class B_class : public A_class char phone_num 20 ; public : void put_phone( char * num ) strcpy ( phone_num , num ) ; void show_phone() cout phone_num “n“ ; ;,例1 使用基类指针引用派生类对象,2. 基类指针引用派生类对象,#include #include class A_class ; class B_class : public A_class ; void main() A_class A_obj ; B_class B_obj ; A_class * A_p = / A_p - show_phone() ,例1 使用基类指针引用派生类对象,对基类指针强类型转换 调用派生类的成员函数,/ myHeader.h class Base public: void show() cout “Base“endl ; ; class Derv1: public Base public: void show() cout “Derv1“endl ; ; class Derv2: public Base public: void show() cout “Derv2“endl ; ;,例2 基类指针中调用同名成员函数,#include #include “m

温馨提示

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

评论

0/150

提交评论