cly

博客园 首页 新随笔 联系 订阅 管理

从系统实现的角度看,多态性分为两种,静态多态性与动态多态性

静态多态性:函数重载、运算符重载(本质上也是函数重载);

动态多态性:在程序运行过程中才动态地确定操作所针对的对象,又称为运行时的多态性,一般通过虚函数(virtual function)实现。

C++通过虚函数与指向基类的指针一起来实现多态

  1. 当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数,因此在派生类中重新声明该虚函数时,可以加virtual,也可以不加,但最好加virtual,使程序清晰。
  2. 如果在派生类中没有对基类中的虚函数重新定义,则派生类继承其直接基类的虚函数。

静态关联:在编译时即可确定其调用的虚函数属于哪一个类,如函数重载与通过对象名调用的虚函数

动态关联:在运行阶段把虚函数和类对象绑定在一起

何时申明虚函数

  1. 首先成员函数所在的类是否会作为基类,其次成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般要设为虚函数
  2. 如果成员函数在类被继承后功能不需要修改,或派生类用不到该函数,则不要把它设为虚函数
  3. 考虑对成员函数的调用时通过对象名还是基类指针或者引用,若是通过基类指针或引用去访问,则应设为虚函数
  4. 有时,在定义虚函数时,并不定义函数体(其函数体是空的),只是定义了一个虚函数名,具体功能留给派生类去添加。

使用虚函数,系统有一定的空间开销,当一个类有虚函数时,系统会为该类构造一个虚函数表(一个指针数组,存放每个虚函数的入口地址)

若一个类中有虚函数,则实例化该类时,对象的第一个成员将是一个指向虚函数表的指针。

纯虚函数,抽象类

virtual int f() = 0;//声明纯虚函数

若一个类中有纯虚函数,则该类为抽象类,抽象类不能实例化,只能用作继承基类

View Code
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 //定义基类-动物类
 6 class Animals
 7 {
 8 public:
 9     Animals();//定义构造函数
10     Animals(int);//带一个参数的构造函数
11 public:
12     int id;
13 public:
14     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
15 };
16 
17 Animals::Animals(){}//实现构造函数
18 Animals::Animals(int id):id(id){}//实现构造函数,初始化成员列表在定义时不指定,函数实现时才指定
19 void Animals::Action()//实现成员函数
20 {
21     cout<<"Animal's action"<<endl;
22 }
23 
24 
25 //定义派生类-人类
26 class Person:public Animals
27 {
28 public:
29     Person(int,int,int);//定义构造函数,实现时才调用父类构造函数
30 public://成员变量
31     int weight;//体重
32     int height;//身高
33 public://成员函数
34     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
35 };
36 //实现派生类构造函数,并显示调用基类构造函数
37 Person::Person(int weight,int height,int id):Animals(id)
38 {
39     this->weight = weight;
40     this->height = height;
41 }
42 
43 //实现派生类成员函数
44 void Person::Action()
45 {
46     cout<<"person's action: walk"<<endl;
47 }
48 
49 //定义派生类-猴类
50 class Monkey:public Animals
51 {
52 public:
53     Monkey(int,int,int);//定义构造函数,实现时才调用父类构造函数
54 public://成员变量
55     int weight;//体重
56     int height;//身高
57 public://成员函数
58     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
59 };
60 //实现派生类构造函数,并显示调用基类构造函数
61 Monkey::Monkey(int weight,int height,int id):Animals(id)
62 {
63     this->weight = weight;
64     this->height = height;
65 }
66 
67 //实现派生类成员函数
68 void Monkey::Action()
69 {
70     cout<<"monkey's action: jump"<<endl;
71 }
72 
73 int main()
74 {
75     //定义动物类对象
76     Animals a;
77     //定义动物类指针
78     Animals * pi;
79     pi = &a;
80     //通过指针调用行为
81     pi->Action();
82     Person b(10,10,0001);
83     pi = &b;//改变指针指向person
84     pi->Action();
85     Monkey c(10,10,0002);
86     pi = &c;//改变指针指向monkey
87     pi->Action();
88     return 0;
89 }
posted on 2012-07-03 00:06  戒色  阅读(351)  评论(0编辑  收藏  举报