继承性为实现多态性提供了两个基本条件: (1)在具有派生层次结构的各个类中,可以定 义同原型而操作各异的成员函数,为不同类的 对象响应同一消息实现多样性提供了条件。 (2)使用基类指针既可以访问基类对象又可 以访问派生类对象,为动态确定接收同一消息 的不同类对象提供了条件。 擎只有这两个条件能否实现多态性呢? 2025/4/6
继承性为实现多态性提供了两个基本条件: 只有这两个条件能否实现多态性呢? (1)在具有派生层次结构的各个类中,可以定 义同原型而操作各异的成员函数,为不同类的 对象响应同一消息实现多样性提供了条件。 (2)使用基类指针既可以访问基类对象又可 以访问派生类对象,为动态确定接收同一消息 的不同类对象提供了条件。 2025/4/6 6
例题6-1、派生类对象替换基类对象 #include <iostream.h> class Pet 1/基类 public: void speak({cout<<"How does a pet speak ?"<<endl;} }; class Cat public Pet /派生类Cat public: void speak(cout<<"miao!miao!"<<endl; }; class Dog public Pet /派生类D0g public: void speak() cout<<"wang!wang!"<<endl; a25146
#include <iostream.h> class Pet //基类 {public: void speak() { cout<<"How does a pet speak ?"<<endl; } }; class Cat : public Pet //派生类Cat {public: void speak() { cout<<"miao!miao!"<<endl; } }; class Dog : public Pet //派生类Dog {public: void speak() { cout<<"wang!wang!"<<endl; } }; 例题6-1、派生类对象替换基类对象 2025/4/6 7
void main() Pet pl,*ptr=&pl; IA Dog dogl; 输出如下: Cat cat1; ptr->speak();//B How does a pet speak? ptr=&cat1; ptr->speak(); IIC How does a pet speak? ptr=&dogl; ptr->speak();//D How does a pet speak? 解决方法:采取“动态连接”的方式进行 编译,即引入虚函数。 25/4
void main() { Pet p1,*ptr=&p1; //A Dog dog1; Cat cat1; 输出如下: ptr->speak(); //B ptr = &cat1; ptr->speak(); //C ptr = &dog1; ptr->speak(); //D } How does a pet speak? How does a pet speak? How does a pet speak? 原因:在编译过程中,当编译到A行时,将实例*ptr中 的函数speak ()确定为类Pet中的成员函数,且采用的是 “静态联编”方式,在运行过程中,不管ptr指向哪个派 生类对象,函数ptr->speak()都不会改变为派生类的版本。 解决方法:采取“动态连接”的方式进行 编译,即引入虚函数。 2025/4/6 8
6.3虚函数 内容提要 、 虚函数 二、虚函数的实现原理(虚函数表) 三、小结 2025/4/6
6.3 虚函数 内 容 提 要 一、虚函数 二、虚函数的实现原理(虚函数表) 三、小 结 2025/4/6 9
虚函数 虚函数是一种非静态的成员函数,说明虚函数的方法 如下: virtual《类型〉 〈函数名〉(〈参数表〉) 虚函数具有如下特征: ①虚函数是在基类和派生类中说明相同而实现不同 的成员函数。 ②基类中说明的虚函数具有下传给派生类的性质。 ③构造函数不能说明为虚函数,而析构函数可以说 明为虚函数。 2025/4/6
2025/4/6 10 虚函数是一种非静态的成员函数,说明虚函数的方法 如下: virtual 〈类型〉〈函数名〉(〈参数表〉) 虚函数具有如下特征: ① 虚函数是在基类和派生类中说明相同而实现不同 的成员函数。 ② 基类中说明的虚函数具有下传给派生类的性质。 ③ 构造函数不能说明为虚函数,而析构函数可以说 明为虚函数。 一、 虚函数