非常感激我队友大爹给我的复习资料

虚函数的作用

  • 允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

当把基类的某个成员函数声明为虚函数后,允许在其派生类中对该函数重新定义,赋予它新的功能,并且可以通过指向基类的指针指向同一类族中不同类的对象,从而调用其中的同名函数。由虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应。

有时在基类中定义的非虚函数会在派生类中被重新定义, 如果用基类指针调用该成员函数, 则系统会调用对象中基类部分的成员函数; 如果用派生类指针调用该成员函数, 则系统会调用派生类对象中的成员函数, 这并不是多态性行为(使用的是不同类型的指针), 没有用到虚函数的功能。

虚函数的使用方法

  1. 在基类用virtual声明成员函数为虚函数;这样就可以在派生类中重新定义此函数, 为它赋予新的功能, 并能被方便的调用。在类外定义虚函数时, 不必再加virtual;
  2. 在派生类中重新定义此函数, 要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同, 并根据派生类的需要重新定义函数体;
  3. 定义一个指向基类对象的指针变量, 并使它指向同一类族中需要调用该对象的函数;
  4. 通过该指针变量调用此虚函数, 此时调用的就是指针变量指向的对象的同名函数。通过虚函数与指向基类对象的指针变量的配合使用, 就能方便的调用同一类族中不同类的同名函数, 只要先用基类指针指向即可;

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>
using namespace std;

// 声明基类Student
class Student {
protected:
int _num;
string _name;
double _score;
public:
Student(int num, string name, double score) : _num(num), _name(name), _score(score) {};
virtual void display() {
cout << "num: " << _num << " name: " << _name << " score: " << _score << endl;
}
};

// 声明公用派生类Graduate

class Graduate : public Student {
private:
double _pay;
public:
Graduate(int num, string name, double score, double pay) : Student(num, name, score), _pay(pay) {};
void display() {
cout << "num: " << _num << " name: " << _name << " score: " << _score << " pay: " << _pay << endl;
}
};

int main(void){
Student st(1001, "Li", 55.8);
Graduate gr(2001, "Wang", 87, 534.5);
Student * p = &st;
p->display();
p = &gr;
p->display();
/*
st.display();
gr.display();
效果与上面一样
*/
return 0;
}

/*
改成虚函数前:
================================
num: 1001 name: Li score: 55.8
num: 2001 name: Wang score: 87
================================
在Student类中声明display()函数时加上virtual关键字后:
================================
num: 1001 name: Li score: 55.8
num: 2001 name: Wang score: 87 pay: 534.5
================================
这就是多态性,对同一消息,不同对象有不同的响应方式。
*/