多态性,虚函数与纯虚函数(复习干货)
向对象发送同一个消息,不同的对象在接收时会产生不同的
行为(即方法,属于本对象的行为)。
- 多态分为静态多态性和动态多态性。
- 静态多态性,函数重载和运算符重载都属于静态多态性。
- 动态多态性,通过虚函数实现。
-
静态多态性:编译阶段确定函数地址(地址早绑定)。
函数调用速度快,效率高,但是缺乏灵活性。
动态多态性:运行阶段确定函数地址(地址晚绑定)。
利用虚函数实现动态多态性
- 所谓虚函数,就是在基类中声明函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式定义此函数。
- 虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应。
- 虚函数
- 基类中声明(virtual),在类外定义虚函数不必在函数名前加virtual,函数体可以是空,它的作用只是定义了一个虚函数名,具体功能留给派生类去添加实现。
- 在派生类中声明时,virtual可以写,也可以不写,但习惯性一般在每一层声明该函数时都加virtual,使程序更加清晰。
- 在派生类中重新定义此虚函数,函数类型,函数名,函数参数个数及参数类型必须与基类的虚函数相同。
-
虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
Base类.h文件
#include<iostream>
usaing namespace std;
class Base
{
public:
Base(int a, int b){ this->a = a; this->b = b;}
virtual void display();
private:
int a;
int b;
};
基类.cpp文件
#include"Base.h"
void Base::dispaly()
{
cout<<"我是基类"<<endl;
cout<<"a="<<a<<"\t"<<"b="<<b<<endl;
// 可以是空
}
派生类.h文件
#include"Base.h"
class Son :
public Base
{
public:
Son(int a, int b, int c):Base(a,b){this->c = c;}
virtual void display();
private:
int c;
};
派生类 .cpp文件
#include"Son.h"
void Son::display()
{
cout<<"我是Son的虚函数"<<endl;
cout<<"a = "<<a<<"\tb="<<b<<"\tc="<<c<<endl;
}
main函数
#include"Son.h"
int main()
{
Son s(1,2,3);
Base *p = s;
p->display();
return 0;
}
运行结果:
我是Son的虚函数
a=1 b=2 c=3
纯虚函数
-
什么是抽象类?
凡是包含纯虚函数的类都是抽象类。由于它常作为基类,通常称为抽象基类。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的(可以建立基类的指针或引用),抽象类的作用是作为一个类族的共同基类,或者说,为一个类族提供一个公共接口。(顶部可以有好几层都是抽象类)
- 静态成员函数不能定义为虚函数,也不能定义成纯虚函数。
- 定义这些抽象类的唯一目的是用它作为基类去建立派生类。
-
什么是具体类?
在抽象类所派生的新类中对基类的所有纯虚函数进行定义,那么这些函数就被赋予了功能,可以被调用,这个派生类就不是抽象类,而是可以定义对象的具体类。
- 如果在派生类中没有对所有纯虚函数进行定义,则此派生类仍然是抽象类,不能定义对象。
- 当派生类成为具体类后,就可以用基类指针指向派生类对象,用指针调用虚函数,实现多态。
- 派生类对基类的纯虚函数进行定义后,该函数就成为了虚函数,而不是纯虚函数。
-
纯虚函数声明: virtual 函数类型 函数名 (参数列表) = 0;
只需要声明,不需要在基类具体实现。
声明如下:
virtual void display() = 0;
- 派生类中必须与基类拥有相同的函数类型,函数名,参数个数以及参数类型。
基类 .h文件
#include<iostream>
using namespace std;
class Shape
{
public:
virtual double area() = 0;
virtual void display() = 0;
};
派生类 .h文件
#include "Shape.h"
class Triangle :
public Shape
{
//三角形
public:
Triangle(int side, int high) { this->side = side; this->high = high; }
virtual double area();
virtual void display();
private:
int side;
int high;
};
派生类 .cpp文件
#include "Triangle.h"
double Triangle::area()
{
return (double)side * high * (1.0/2);
}
void Triangle::display()
{
all_area += area();
cout << "Triangle的面积是:" << area() << endl;
}
main函数
#include"Triangle.h"
int main()
{ Triangle e(2, 4);
Shape* pt;
pt = &e;
pt->display();
运行结果:
Triangle的面积是:4