Presentation is loading. Please wait.

Presentation is loading. Please wait.

谭浩强编著 C++面向对象程序设计 授课教师:姬广永 学习网站:

Similar presentations


Presentation on theme: "谭浩强编著 C++面向对象程序设计 授课教师:姬广永 学习网站:"— Presentation transcript:

1 谭浩强编著 C++面向对象程序设计 授课教师:姬广永 学习网站:http://www.xin126.cn

2 第六章多态性与虚函数 多态性的概念 一个典型的例子 虚函数 纯虚函数与抽象类

3 第六章多态性与虚函数 什么叫多态? 多态的意思是一个事物有多种形态。 在C++中,是指具有不同功能的函数可以用同一个函数名。
面向对象程序设计中:多态性是指向不同的对象发送同一个消息,不同对象在接收时会产生不同的行为。不同的行为就是指不同的实现方法,即执行不同的函数体。

4 虚函数:运行时的多态性 编译时的多态性(函数重载) 运行时的多态性(虚函数) 多态性
运行时的多态性是指在程序执行之前,根据函数名和参数无法确定应该调用哪一个函数,必须在程序的执行过程中,根据具体的执行情况来动态地确定

5 编译时的多态性(函数重载) int add(int x, int y) { return x+y; }
  double add(double a, double b)   {   return a+b; } int main()   { cout<<add(5, 10) <<endl;    cout<<add(5.0, 10.5) <<endl;   }

6 一个典型的例子 class A{ public: void show() { cout<<"A"<<endl; }
}; class B:public A { public: void show() { cout<<"B"<<endl; } class C:public B { public: void show() { cout<<"C"<<endl; }

7 int main() { C c; c.show(); c.B::show(); c.A::show(); }

8 虚函数的作用 c.show(); c.B::show(); c.A::show(); 用这种方法来区分同名函数,不方便。
提出设想:(通过同一种形式达到不同目的) 能否用同一个调用形式,如pt->show();既能调用派生类的函数,又能调用基类的同名函数。

9 pt=&b; pt->show();
class A{ public: void show(){ cout<<"A"; } }; class B:public A { void show(){ cout<<"B"; } int main() { A a, *pt; B b; pt=&a; pt->show(); pt=&b; pt->show(); }

10 pt= &b; pt ->Show(); pt pt只能引用从基类继承来的成员。 A a,*pt; pt=&a; pt
可以将一个派生类对象的地址赋给基类的指针变量。 基类指针 pt只能引用从基类继承来的成员。 A a,*pt; pt=&a; 派生类对象 pt= &b; pt ->Show(); 派生类对象 b 基类对象a pt pt Show() Show() Show() pt->Show()

11 运行时的多态性(虚函数) 虚函数的作用:是允许在派生类中重新定义与基类同名的函数,并且可以通过基类的指针或引用来访问基类和派生类中的同名函数。

12 虚函数的定义 定义虚函数的方法如下: virtual 函数类型 函数名(形参表) { // 函数体 }
// 函数体 } c++规定:当一个成员函数声明为虚函数后,其派生类中的同名函数都自动成为虚函数。在派生类中重新定义基类中的虚函数时,可以不用关键字virtual来修饰这个成员函数 。

13 pt=&b; pt->show();
class A{ public: virtual void show(){ cout<<"A"; } }; class B:public A { void show(){ cout<<"B"; } int main() { A a, *pt; B b; pt=&a; pt->show(); pt=&b; pt->show(); }

14 虚函数与重载函数的区别 在一个派生类中重新定义基类的虚函数是函数重载的另一种形式,但它不同于一般的函数重载。
◆ 普通的函数重载:函数名相同,参数不同(参数个数或类型不同)。 ◆ 当重载一个虚函数时,也就是说在派生类中重新定义虚函数时,要求函数名、返回类型、参数个数、参数的类型和顺序与基类中的虚函数原型完全相同。 ◆ 如果仅仅返回类型不同,其余均相同,系统会给出错误信息; ◆若仅仅函数名相同,而参数个数或类型不同,系统将它作为普通的函数重载,这时将丢失虚函数的特性。

15 虚函数的限制: 1.必须是成员函数 2.不能是静态成员函数 3.不能是inline函数 4.构造函数不能是虚函数

16 纯虚函数和抽象类 纯虚函数: 是一个在基类中说明的虚函数,只有函数声明,没有函数体,不能被调用。 纯虚函数的定义形式如下:
virtual 函数类型 函数名(参数表)=0; “=0 ”不表示函数的返回值为0,它只起形式上的作用,告诉编译系统“这是虚函数”,它的实现留给派生类去定义。

17 virtual void show()=0; // 纯虚函数
纯虚函数的使用: class Circle { protected: int r; public: void setr(int x){ r=x; } virtual void show()=0; // 纯虚函数 }; class Area:public Circle{ public: void show() { cout<<"Area is "<<3.14*r*r<<endl;} }; // 重定义虚函数show( ) class Perimeter:public Circle{ void show() {cout<<"Perimeter is "<<2*3.14*r<<endl;} }; // 重定义虚函数show( )

18 void main() { Circle *ptr; Area ob1; Perimeter ob2; ob1.setr(10);
ptr=&ob1; ptr->show(); ptr=&ob2; }

19 6.4 抽象类 如果一个类包含纯虚函数,那么就称该类为抽象类。 抽象类只能作为其他类的基类来使用 不能建立抽象类对象
6.4 抽象类 如果一个类包含纯虚函数,那么就称该类为抽象类。 抽象类只能作为其他类的基类来使用 不能建立抽象类对象

20 例 8-5 void display(){cout<<"C::display()"<<endl;}
class A //抽象基类B0声明 { public: //外部接口 virtual void display( ) =0; //纯虚函数成员 }; class B: public A //公有派生 { public: void display(){cout<<"B::display()"<<endl;} class C: public A //公有派生 void display(){cout<<"C::display()"<<endl;}

21 p->display(); //调用派生类B函数成员 p= &c; p->display(); //调用派生类C函数成员 }
int main() //主函数 { A *p; //声明抽象基类指针 B b; //声明派生类对象 C c; //声明派生类对象 p=&b; p->display(); //调用派生类B函数成员 p= &c; p->display(); //调用派生类C函数成员 } 21

22 抽象类的作用: 抽象类为抽象和设计的目的而声明,是更高层次的抽象。 将有关的数据和行为组织在一个继承层次结构中,保证派生类具有要求的行为。
如抽象基类shape(包含纯虚函数draw())派生出4个类:Square(正方形)、Circle、Rectangle(矩形)、Triangle(三角形),各个派生类定义自己的draw函数,作用分别是在屏幕上画出正方形、圆、矩形、三角形。

23 抽象类的作用:代码重用 、灵活 class ring { public: virtual void Set ( ) =0; } ;
…… public: virtual void Set ( ) =0; } ; class diamond_ring :public ring { void Set ( ){…} } class jewel _ring :public ring 抽象类限制了戒指的部分特性,也预留了部分灵活性

24 课后习题P219 4.


Download ppt "谭浩强编著 C++面向对象程序设计 授课教师:姬广永 学习网站:"

Similar presentations


Ads by Google