浙大翁恺c++笔记:继承及c++多态如何实现


要了解多态,首先需要掌握继承和向上类型转换。继承这里不做介绍请自行百度。

向上类型转换

在这里插入图片描述
如上图的继承关系。我们假设有一个Shape和一个Ellipse对象。

Shape s;
Ellipse e;
Shape *s_ptr = &e;//正确,我们可以将一个派生类赋值给一个基类的引用或者指针
Ellipse *e_ptr = &s;//错误,不可以将基类赋值给派生类的对象或者引用

其实不难理解我们看到派生类的指针,肯定会使用指针访问派生类的成员,但是此时指向的是基类对象,基类对象一定不会包含派生类新增的成员此时就出现了问题。
我们只要记住向上(基类)类型转换,所以基类指针或引用可以接收任何派生而出的对象即可。

了解向上类型转换我们接下来看虚函数与动态绑定;

虚函数与动态绑定

在上图的继承关系中看到,成员函数中只有不同类的render()方法行为不同,故我们需要在派生类中重写render()方法。结合向上类型转换那么问题就来了,s_ptr->render();到底调用了哪个render()函数。

Shape *s_ptr = &e;
s_ptr->render();

我们肯定是要调用Ellipse的render()函数。因为这样我就可以仅仅使用一个Shape的指针调用所有派生类重写的函数。比如:

Circle c;
Shape *s_ptr = &c;
s_ptr->render();//此时又可以调用Circle的render函数

OK,确定了s_ptr调用哪个函数之后。又如何通过一个基类指针根据所指派生类不同来调用不同的函数呢。
答案就是动态绑定。动态绑定的实现方法其实特别简单,只要你会指针你就能实现动态绑定。
在这里插入图片描述
我们将基类中需要重写的函数声明为virtual,含有virtual函数的类创建对象时会比普通对象多一个指针vtable,这个指针指向这些虚函数的首地址。当我们使用基类的指针指向派生类对象时,派生类对象通过这个指针就找到属于自己类的虚函数了。

注意函数是属于类的,不管是成员函数还是虚函数,在程序中只存在一份,并不会因为对象的增加而增加。就是说所有派生类的vtable指针指向的是同一片内存空间。

这就是c++多态的实现,是不是很简单呢HH。
补充:
我在验证vtable指针存在的时候遇到了一个问题
在这里插入图片描述
我必须将int *的指针下移两次才访问到了a的数据成员,这就意味着vtable占据了两个int的位置,按照我的理解int是计算机一次数据处理的长度。我的机器是64位机vtable占两个int就是64位,可以访问所有地址。但为什么我的一个int是32位呢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值