C++的三大特性:封装、继承、多态。封装可以使得代码模块化,继承可以扩展已存在的代码,而多态的目的则是为了接口重用。下面主要以介绍多态为主。
什么是多态
C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。
多态性指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。
a、编译时多态性(静态多态):通过重载函数实现
b、运行时多态性(动态多态):通过虚函数实现。
编译时多态:
又称编译期多态,即在系统编译期间就可以确定程序将要执行哪个函数。例如:函数重载,通过类成员运算符指定的运算。
class A {
public:
A() {}
A( int x ) {}
void fun() {}
void fun( int x ) {}
};
class B {
public:
B() {}
void fun() {}
void fun( int x ) {}
};
运行时多态:
最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。因为没有多态性,函数调用的地址将是一定的,而固定的地址将始终调用到同一个函数,这就无法实现一个接口,多种方法的目的了。
多态的用法
注意:
1、用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
2、存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
3、多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
4、多态用虚函数来实现,结合动态绑定.
5、纯虚函数是虚函数再加上 = 0;
6、抽象类是指包括至少一个纯虚函数的类。
#include <iostream>
using namespace std;
class Base
{
public:
// 父类虚函数必须要有 virtual 关键字
virtual void fun_test()
{
cout << "parent class" << endl;
}
void test()
{
cout << "is parent" << endl;
}
};
class Derived : public Base
{
public:
// 子类有没有 virtual 关键字都可以
void fun_test()
{
cout << "child class" << endl;
}
};
int main(int argc, char const *argv[])
{
Base *p = NULL; // 创建一个父类的指针
Derived child;
p = &child; // 指向子类的对象
p->fun_test(); // 执行的是子类的 fun_test() 函数
return 0;
}
输出结果:
扫描二维码关注公众号,回复:
8941778 查看本文章
编译器在编译的时候,发现Base类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表(即 vtable),该表是一个一维数组,在这个数组中存放每个虚函数的地址。
C++运行时多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(Override),或者称为重写。
参考:
https://www.cnblogs.com/cxq0017/p/6074247.html