多态
多态性可以简单的概括成“一个接口多种方法”,这是面向对象编程的核心概念,多态性指相同对象收到不同消息或不同对象收到相同消息时产生的不同的实现动作,C++主要有两种多态性:编译时多态性(静态多态性,通过重载函数实现)和运行时多态性(动态多态性,通过虚函数实现)。虚函数允许子类重新定义成员函数,而子类重新定义父类的做法成为覆盖或者是重写。C++三大特性中另外两个封装使得代码模块化,继承可以扩展已存的代码,这两个的目的都是为了代码重用,而多态是为了“接口重用”——不管传递的是类的哪个对象,函数都能通过同一个接口调用到适应各自对象的实现方法。多态最常用的做法就是声明基类类型的指针,利用这个指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法,这是如果没有虚函数就没有利用C++多态性,使用基类指针的时候就只会被限制在基类函数本身,无法调用子类被重写过的函数。
需要注意:虚函数只适用于有继承关系的类对象,普通函数不能声明虚函数,静态成员函数不能是虚函数,因为静态成员函数是属于一个类的不能局限余一个对象,內联函数不能是虚函数,因为內联函数不能在运行中动太确定位置,构造函数不能是虚函数,析构函数可以是虚函数并且推荐变为虚函数。
函数重写,重载和隐藏是有区别的,重写可以用来重写虚函数和成员函数,只有重写了虚函数才能体现多态的特性,而重载是运行有多个同名的函数,但是这些函数的参数列表是不同的,重载允许参数个数不同或是参数类型不同,编译器会根据不同的函数列表生成不同名称的预处理函数,来实现同名函数调用时的重载问题,但是重载其实本质上并没有体现多态性。隐藏是指当派生类和基类函数重名但是参数不同时,无论有无virtual关键字基类函数都会被隐藏(与重载不同,重载是发生在同一个类中的),如果派生类和基类函数名相同,但是参数也相同,并且没有virtual那么基类函数也会被隐藏(与重写区分,重写是有virtual关键词)。
参考资料:浅谈C++ 多态,c++多态。
虚函数
虚函数是多态的一种实现方式,而多态是:“多态(英语:polymorphism),是指计算机程序运行时,相同的消息可能会送给多个不同的类别之对象,而系统可依据对象所属类别,引发对应类别的方法,而有不同的行为。简单来说,所谓多态意指相同的消息给予不同的对象会引发不同的动作称之。”其实更简单地来说,就是“在用父类指针调用函数时,实际调用的是指针指向的实际类型(子类)的成员函数”。多态性使得程序调用的函数是在运行时动态确定的,而不是在编译时静态确定的,这点在上文也有讲过。而虚函数则是加了virtual修饰词的类的成员函数。
#include <iostream>
using namespace std;
int main(int argc, char const *argv[]){
class base{
public:
virtual void vir_func(){
cout<<"virtual function, this is class base"<<endl;}
void func() {
cout<<"normal function, this is class base"<<endl;}
};
class A:public base{
public:virtual void vir_func(){
cout<<"virtual function, this is class A"<<endl;}
void func(){
cout<<"normal function, this is class A"<<endl;