C++ 的多态性与虚函数
腾讯二面时被问到关于C++的多态性和虚函数,当时脑袋发热没回答好,其实根本原因是这是很久之前看的,而且一直没有应用上,所以理所当然说不出个所以然来。趁着国庆假期,把C++草草捡了些回来,现在主要说下多态性和虚函数。
一、多态性:
顾名思义,多态的意思的一个事物有多种形态。在C++中,多态性是指具有同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。即向不同的对象发送同一个消息,不同的对象在接收会产生不同的行为。(通俗:当学校校长向社会发布一个消息:9月1号开学。不同的对象会做出不同的响应:学生准备好课本回学校上课,老师备好课回学校教学……)
多态性分两类:静态多态性和动态多态性。
静态: 如函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能决定调用的是哪个函数,因此静态多态性又称编译时的多态性。
动态: 动态多态性的程序运行过程中才动态确定操作所针对的对象,所以多态多态性又称运行时的多态性。动态多态性是通过虚函数实现的。
二、虚函数
虚函数的作用允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
虚函数的声明: virtual 函数类型 函数名();
C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。
纯虚函数是在声明虚函数时被“初始化”为0的函数 :virtual 函数类型 函数名(参数列表) =0;
PS:(1)纯虚函数没有函数体,只有函数的而不具备函数的功能,不能被调用。只有在派生类中对此函数提供定义后,它才具备函数的功能, 可以被调用。(2)凡是包含纯虚函数的类都是抽象类,因为纯虚函数不能被调用,所以抽象类是无法建立对象的。
1 //声明基类 Person
2 class Person
3 {
4 public:
5 Person(int,string);
6 virtual void display(); //声明为虚函数
7 protected:
8 int age;
9 string name;
10 };
11 Person::Person(int n,string nam):age(n),name(nam);
12 void Person::display()
13 {
14 cout<<"age:"<<age<<" name:"<<name<<endl;
15 }
16 //声明派生类Student
17 class Student:public Student
18 {
19 public:
20 Student(int,string,float);
21 void display(); //虚函数
22 private:
23 float score;
24 };
25 Student::Student(int n,string nam,float s):Person(n,nam),score(s){}
26 void Student::display()
27 {
28 cout<<"age:"<<age<<" name:"<<name<<" score:"<<score<<endl;
29 }
30
31 int main()
32 {
33 Person p (20,"Zhang");
34 Student s (25,"Wang",95);
35 Person *pt = &p;
36 pt->display();
37 pt = *s;
38 pt->display();
39 return 0;
40 }
输出结果为:age:20 name:Zhang
age:25 name:Wang score:95
如果第6行代码写成:void display(); 即不把display声明为虚函数,
则输出结果为:age:20 name:Zhang
age:25 name:Wang