C++多态的实现

C++多态的分类

C++多态分为两类:

静态多态

静态多态是在编译期间就可以确定函数的调用地址,也称为早绑定。
静态多态一般通过函数重载实现,即函数名相同,根据参数的类型不同实现多态。

int add(int x,int y) {
    return x+y;
}

float add(float x,float y) {
    return x+y;
}

另外一种方法就是C++的模版,即泛型编程,相比函数重载,因为代码量的大幅度减少,所以可以降低我们开发的错误率。同样是上述的例子,数据类型还有好几种,如果要考虑全面的话就要把所有的类型对应的函数都写一遍,但是用模版就简单了许多:

template <typename T>
T add(T x, T y) 
{
    return x+y;
}

动态多态

动态多态是在运行期间可以确定函数的调用地址,称为晚绑定。
动态多态大多需要继承有虚函数的基类,所以需要先对虚函数、虚表、虚函数指针等进行介绍。

在创建一个空类的时候,在内存中只有一个字节的占位符,在向类中加入了数据(任何成员函数都不隶属于对象,所以普通成员函数不占用内存)之后也会占有更多的内存,但是不论类中有多少个虚函数都只是占有四个字节,这四个字节就是用来存放一个指向虚函数表的指针,通过这个虚函数表中位置进行偏移找到类中定义的所有虚函数。

class  base
{
    public:
        virtual void fun_a();
        virtual void fun_b();
};

这里写图片描述

C++中多态的实现其实就是在派生类中重写虚函数,运行的时候会根据对象的实际类型查找相应的虚函数表,从而来调用相应的虚函数。
在运行的时候根据对象的实际类型查找到的虚函数表是什么样子?这使我们接下来要探究的主要方向。

把上面的类base当作基类,主要有一下几种继承情况:

1)继承基类,并重写基类的虚函数:

class A : public base
{
public:
    virtual void fun_a();
    virtual void fun_1();
}

这个时候A的虚函数表变成下图所示:
这里写图片描述

可以看出,在派生类的虚函数表中,最前面的函数指针为基类中的虚函数指针,自己的虚函数指针放在基类虚函数地址后面,但是在派生类中重写的虚函数会将虚函数表中基类的虚函数指针替换为派生类中重写的该函数指针,例如本例中将base::fun_a()替换为A::fun_a()。

2)普通继承没有重写基类中的虚函数
从1)中也可以很容易的看出,这种继承后虚函数表就是将基类中的虚函数放在前面,将自己的虚函数放在后面(按照声明的顺序)。

3)派生类继承多个基类
当派生类继承多个基类的时候,派生类实例中也会继承基类的多个虚函数表,即会有多个虚函数表指针,每个虚函数表的前部分也是对应基类的虚函数指针。

纯虚函数

纯虚函数是最容易理解C++的多态性的,它只是在基类中定义一个接口,其中的具体实现都是在子类中实现,这样不同的对象实例调用的自然是不同的接口函数。

纯虚函数的定义方法如下:

class base
{
public:
    virtual void fun() = 0;
}

这样当子类继承base类的时候在子类中实现fun函数,不同的子类有不同的函数内容,从而实现了多态。

把含有纯虚函数的类称为抽象类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值