上岸充通大 1896 006 C++程序设计与实践 第7讲C++类(2) 上海交通大学 漏 机械与动力工程学院 2014.9-2015.1 上泽充通大¥ 1896 1920 1. 类的多态性 2.标准库vector类的使用 3.标准库string类的使用 4.面向对象的程序设计 SH 1
1 C++程序设计与实践 上海交通大学 机械与动力工程学院 2014.9-2015.1 第7讲 C++类(2) 1. 类的多态性 2. 标准库vector类的使用 3. 标准库string 类的使用 4. 面向对象的程序设计 5. 类的使用
多个闹钟的管理 1 2 3 1115 4、 > Clock 闪烁 Alarm() 闹声 闹声 振动 国上清夫道大些 3/30 多个闹钟的管理 闹钟功能 子类 DigitalClock Alarm() 振动 父类 Clock AuditoryClock Alarm() 闹声 Alarm() Clock *cl1 new DigitalClock; AnalogClock 闪烁 cl1->Alarm(); Alarm( 根据函数名和参数无法确定应该调用哪一个函数,必须在程序 的执行过程中,根据具体的执行情况来动态地确定 圈上海大大学 4/30 2
2 3/30 多个闹钟的管理 Clock Alarm() 振动 闹声 闪烁 闹声 4/30 多个闹钟的管理 闹钟功能 根据函数名和参数无法确定应该调用哪一个函数,必须在程序 的执行过程中,根据具体的执行情况来动态地确定 Clock Alarm() AnalogClock Alarm() DigitalClock Alarm() Clock *cl1 = new DigitalClock; 父类 cl1->Alarm(); ? 子类 振动 闹声 闪烁 AuditoryClock Alarm()
继承法 Clock 什么都不做 任务: Alarm() 批量实现不同时钟的闹钟动作 多个类:AnalogClock,DigitalClock 首先判断是属于什么时钟,才能调用 AnalogClock DigitalClock 相应的Alaram()函数 Alarm() Alarm() Clock clock1; DigitalClock c1; clock1.Alarm(; Clock *pc1=&c1; 闪烁 振动 pc1->Alarm(); DigitalClock c1; Clock *p1=&c1; 实际调用的是Clock类中 p1->Alarm(); Alarm( 图上清夫道大学 530 继承法 class Clock public: ClockO void Alarm(void)cout<<"Clock Alarm!"<<endl;} 继承 class DigitalClock:public Clock public: DigitalClock( void Alarm(void){cout<<Digital Alarm!"<<endl;) void main(void) Clock *pClock=NULL; DigitalClock d cl: pClock=&d_cl; pClock->Alarm () 输出:Clock Alarm! } 国上海文大华 630 3
3 5/30 继承法 Clock Alarm() AnalogClock Alarm() DigitalClock Alarm() 任务: 批量实现不同时钟的闹钟动作 首先判断是属于什么时钟,才能调用 相应的Alaram()函数 多个类:AnalogClock, DigitalClock Clock clock1; clock1.Alarm(); DigitalClock c1; Clock *pc1=&c1; 闪烁 振动 pc1->Alarm(); 什么都不做 实际调用的是? Clock类中 Alarm() DigitalClock c1; Clock *p1=&c1; p1->Alarm(); 6/30 class Clock {public: Clock(){} void Alarm(void){cout<<“Clock Alarm!”<<endl;} }; class DigitalClock: public Clock {public: DigitalClock(){} void Alarm(void){cout<<“Digital Alarm!”<<endl;} }; void main(void) { Clock *pClock=NULL; DigitalClock d_cl; pClock=&d_cl; pClock->Alarm (); } 输出:Clock Alarm! 继承 继承法
虚函数 Clock DigitalClock d1; virtual Alarm() AnalogClock a1; Clock *p1=&d1; p1->Alarm(); p1=&a1; AnalogClock DigitalClock p1->Alarm(); Alarm() Alarm() virtual <type>FuncName(<ArgList>); 调用AnalogClock类和 通过基类指针调用派生类函数 DigitalClock类中Alarm0 for (int i=0;i<n;i++) p[i]->Alarm(; 国上清夫道大些 730 虚函数 class Clock public: Clock() virtual void Alarm()cout<<"Clock Alarm!"<<endl; :声明为虚函数 class DigitalClock:public Clock 继承 publie: DigitalClock() void Alarm()(cout<<"Digital Alarm!"<<endl;) 派生类定义 void main(void) {Clock*pCIock=-NULL,∥基类指针,可以将派生类对象的地址赋给基类指 DigitalClock d cl: pClock=&d cl; 调用虚函数 用基类指针调用派生类函数 pClock->Alarm O; 输出:DigitalAlarm! Alarm(声明为虚函数,使派生类与基类的Alarm0函数有一个统一的接口 4
4 7/30 虚函数 Clock virtual Alarm() AnalogClock Alarm() DigitalClock Alarm() 调 用 AnalogClock 类 和 DigitalClock类中Alarm() DigitalClock d1; AnalogClock a1; Clock *p1=&d1; p1->Alarm(); p1=&a1; p1->Alarm(); virtual <type> FuncName(<ArgList>); 通过基类指针调用派生类函数 for (int i=0; i<n; i++) p[i]->Alarm(); 8/30 虚函数 class Clock {public: Clock(){} }; class DigitalClock: public Clock {public: DigitalClock(){} void Alarm( ){cout<<“Digital Alarm!”<<endl;} }; void main(void) { Clock *pClock=NULL; //基类指针,可以将派生类对象的地址赋给基类指针 DigitalClock d_cl; pClock=&d_cl; pClock->Alarm (); } 派生类定义 调用虚函数 Alarm()声明为虚函数,使派生类与基类的Alarm ()函数有一个统一的接口 virtual void Alarm( ){cout<<“Clock Alarm!”<<endl;} //声明为虚函数 继承 输出:DigitalAlarm! 用基类指针调用派生类函数
虚析构函数 Clock virtual ~Clock() Clock *p=new DigtialClock; delete p; AnalogClock DigitalClock 0 ~AnalogClock() -DigitalClock() 实际执行~Clock(); DigitalClockO ClockO *hour=new int;) “清理现场”不干净 } ~DigitalClockO ~Clock() 实际先执行 if(hour!=NULL) ~DigitalClock(), delete hour; hour=NULL;} 再执行~Clock0 先调用派生类的析构函数,再调用基类的析构函数 网上海家大学 91/30 练习1 1. 基类析构函数输出“executing Clock destructor'” 2. 派生类DigitalClock的构造函数用new创建一个double类型的指针变 量hour,析构函数delete这个hour变量并输出“executing DigitalClock destructor" 3. 在main函数中创建DigitalClock变量的指针,并调用虚析构函数 Clock main函数: -Clock() Clock *p new DigitalClock; A delete p; DigitalClock 0 +hour:double +DigitalClock() executing AnalogClock destructor ~DigitalClock() executing DigitalClock destructor 国上海大学 10/30 5
5 9/30 虚析构函数 AnalogClock ~AnalogClock() DigitalClock ~DigitalClock() 实际执行~Clock(); Clock *p=new DigtialClock; delete p; “清理现场”不干净 实际先执行 ~DigitalClock(), 再执行~Clock() 先调用派生类的析构函数,再调用基类的析构函数 Clock ~Clock() DigitalClock() { *hour = new int;} ~DigitalClock() { if(hour != NULL) {delete hour; hour = NULL;} } Clock() { } ~Clock() { } Clock virtual ~Clock() 10/30 1. 基类析构函数输出“executing Clock destructor” 2. 派生类DigitalClock的构造函数用new创建一个double类型的指针变 量 hour ,析构函数 delete 这 个 hour 变量并输出“ executing DigitalClock destructor” 3. 在main函数中创建DigitalClock变量的指针,并调用虚析构函数 executing AnalogClock destructor executing DigitalClock destructor 练习1 main函数: Clock *p = new DigitalClock; delete p;