首页
社区
课程
招聘
[原创]我们聊聊继承吧,从继承的角度出发再来聊聊多态
发表于: 2019-10-15 21:55 4111

[原创]我们聊聊继承吧,从继承的角度出发再来聊聊多态

2019-10-15 21:55
4111


上面的代码中子类虽然没有写构造函数和析构函数,但是编译器还是自动生成了它们,子类构造函数、析构函数和父类的构造函数、析构函数调用顺序如下:

父类构造函数 -> 子类构造函数 -> 子类析构函数 -> 父类析构函数

我们关注的重点并不在这里,而是子类对象和父类对象的关系。

走进ShowNumber函数:

在子类调用父类函数时,直接传递了子类的this指针,我们走进这个SetNumber :

执行结束回到ShowNumber继续执行

由此我们看出父类的nNumber赋值到this的前4个字节,而子类的nNumberChild赋值到this的第四个字节开始的后面四个字节。

那么此时this的内存结构如下图:


由此,我们可以总结出,父类对象在子类对象开始处,那么将上例中的CChild的类修改为下面的样子,则他们的内存结构时完全一样的。

这种内存结构的优势是什么?

很明显,子类对象调用父类的函数,直接传递子类的对象地址就可以了,那么子类对象指针可以强制转换为父类对象指针来使用,反之则不行。

------------------->分割线

再来聊聊多态,上代码:

先来看看输出:


是不是意料之中的结果?

来看看内部实现吧,先从cChild0的构造函数开始吧:

首先调用了父类的构造函数,然后赋值虚表为本类(cChild0)的虚表。

走进cBase的构造函数:

在构造函数中只做一件事,就是赋值虚表为本类(cBase)的虚表。

总结下,在cChild0的构造函数中做了以下的事情:

调用父类构造函数 -> 在父类的构造函数中设置虚表为本类(cBase)的虚表 -> 设置虚表为本类的(cChild0)虚表

需要注意的是,在上文中设置两次虚表都是cChild0 this指针的前四个字节。

在cChild1中做了同样的事情,就不再次赘述了。


那么现在已经很清晰了,这两个子类对象在构造函数调用之后会将虚表都设成自己的虚表。

现在我们来看看GoPrint函数吧:


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-10-16 01:25 被Hasic编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 83
活跃值: (1092)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
全文重点--》 需要注意的是,在上文中设置两次虚表都是cChild0 this指针的前四个字节
2019-10-16 16:29
0
雪    币: 612
活跃值: (479)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
killpy 全文重点--》 需要注意的是,在上文中设置两次虚表都是cChild0 this指针的前四个字节
谢谢您的指点
2019-10-16 21:32
0
游客
登录 | 注册 方可回帖
返回
//