当前位置: 首页 > wzjs >正文

唐山网站建设|唐山网站制作|公司建站666起|唐山红城网络为什么很多中国人去菲律宾做网站

唐山网站建设|唐山网站制作|公司建站666起|唐山红城网络,为什么很多中国人去菲律宾做网站,最新网页游戏开服表,网页设计与网站建设区别C 虚函数、虚函数表详解与实践 C中虚函数是实现多态的重要技术,接下来将从汇编、以及gdb调试运行方面下手全面了解虚函数、虚函数表、以及虚函数调用。 原理初认识 一个由虚函数的类将会有一个虚函数表,且所有该类的实例化对象共享一个虚函数表。虚函…

C++ 虚函数、虚函数表详解与实践

C++中虚函数是实现多态的重要技术,接下来将从汇编、以及gdb调试运行方面下手全面了解虚函数、虚函数表、以及虚函数调用。

原理初认识

  1. 一个由虚函数的类将会有一个虚函数表,且所有该类的实例化对象共享一个虚函数表
  2. 虚函数表将存在代码的.data.rel.ro段中(该段表示需要重定位的只读数据段),在代码(elf可执行文件)的.rela.dyn段中指出了需要重定位的条目。
  3. 每个有虚函数的类的实例化对象都有一个指向该类虚函数表的成员指针变量(编译器自动创建)。
  4. 虚函数的调用会根据对象中的虚函数表去找对应的虚函数地址,然后再去调用对应的虚函数。
  5. 虚函数表的初始化是在编译时期(编译器直接将对应的虚函数地址放入虚函数表中),实例化对象的指向虚函数表的指针初始化是在构造函数中,其中指向虚函数表的指针是实现动态多态的重要技术。
  6. 类的构造函数不能是虚函数(原因见下面2.1的分析)。

一探究竟

1. 测试源代码

#include <iostream>// 父类
class Base {
public:// 纯虚函数virtual void call() = 0;
};// 子类
class SON : public Base {
public:// 重写父类纯虚函数void call() override {std::cout << "vir son call\n";}
};int main()
{Base* myson = new SON;// 调用重写的call函数myson->call();return 0;
}

2. 汇编代码分析

  1. 调用流程分析
    1. main函数中会先调用SON的构造函数。
    2. SON的构造函数中会调用父类Base的构造函数,然后返回SON的构造函数。
    3. SON构造函数中会进行虚函数表指针的初始化(将SON类的虚函数表首地址放入该对象的虚函数表指针中)。
    4. SON构造函数完成剩下其他初始化就返回到main函数中。
  • 由于是先调用父类的构造函数再初始化虚函数表指针,所以如果父类构造函数是虚函数的话,在子类对象虚函数表指针都还没初始化就去调用重写的虚构造函数显然是不行的(因为虚函数表指针都没初始化,怎么能调用到重写的虚构造函数)。

  • 对应的汇编代码截屏
    在这里插入图片描述

  • 虚函数表所对应的.data.rel.ro段,虚函数表地址为0x11d18,其中存放的重写的call函数地址为0xfd8.
    在这里插入图片描述

  • SON类重写的call函数汇编代码截屏(地址分配为0xfd8
    在这里插入图片描述

    • 从图二可以看出,在编译阶段编译器就已经将重写的call地址放入了虚函数表中,所以可以知道了虚函数的初始化是在编译阶段
    • 从上面三张截屏可以看出来在SON的构造函数中会将该类的虚函数地址放入该对象的虚函数表指针中,所以可以知道了对象的虚函数表指针初始化是在构造函数阶段
  1. elf可执行程序执行时,看看虚函数表中对重写的虚函数地址的重定位。
  • .rela.dyn段的截屏,可以看出重定位表项记录了重写的call函数地址需要在加载时重新修改(重定位)
    在这里插入图片描述

  • gdb调试时虚函数表中重写虚函数的实际地址截屏,可以看出确实被重定位了指向了重写的call函数的真实地址
    在这里插入图片描述

  1. 虚函数的调用
    在这里插入图片描述

    // 将实例化myson的this指针放入x0寄存器中
    f38:       f94017e0        ldr     x0, [sp, #40]// 取出myson的第一个成员变量(即虚函数表指针)
    f3c:       f9400000        ldr     x0, [x0]// 访问虚函数表指针指向的空间(即虚函数表第一个表项)并将其放入x1寄存器中(此时x1寄存器中的值就是重写的call函数地址)
    f40:       f9400001        ldr     x1, [x0]// 将myson的this指针放入x0寄存器中
    f44:       f94017e0        ldr     x0, [sp, #40]// 函数跳转至x1寄存器中存放的地址(即重写的call函数地址)
    f48:       d63f0020        blr     x1
    

总结

  • 在此C++虚函数、虚函数表相关的知识点已经全部从实践的角度分析完。相关结论在1.原理初认识的时候就已经给出。

附录重要汇编代码

感兴趣的朋友可以细看

  • .rela.dyn
Relocation section '.rela.dyn' at offset 0xa50 contains 20 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000011cf0  000000000403 R_AARCH64_RELATIV                    f10
000000011cf8  000000000403 R_AARCH64_RELATIV                    fbc
000000011d00  000000000403 R_AARCH64_RELATIV                    ec0
000000011d10  000000000403 R_AARCH64_RELATIV                    11d38
000000011d18  000000000403 R_AARCH64_RELATIV                    fd8
000000011d28  000000000403 R_AARCH64_RELATIV                    11d50
000000011d40  000000000403 R_AARCH64_RELATIV                    1088
000000011d48  000000000403 R_AARCH64_RELATIV                    11d50
  • main函数
0000000000000f14 <main>:f14:       a9bd7bfd        stp     x29, x30, [sp, #-48]!f18:       910003fd        mov     x29, spf1c:       f9000bf3        str     x19, [sp, #16]f20:       d2800100        mov     x0, #0x8                        // #8f24:       97ffff93        bl      d70 <_Znwm@plt>f28:       aa0003f3        mov     x19, x0f2c:       aa1303e0        mov     x0, x19f30:       9400003e        bl      1028 <_ZN3SONC1Ev>f34:       f90017f3        str     x19, [sp, #40]f38:       f94017e0        ldr     x0, [sp, #40]f3c:       f9400000        ldr     x0, [x0]f40:       f9400001        ldr     x1, [x0]f44:       f94017e0        ldr     x0, [sp, #40]f48:       d63f0020        blr     x1f4c:       52800000        mov     w0, #0x0                        // #0f50:       f9400bf3        ldr     x19, [sp, #16]f54:       a8c37bfd        ldp     x29, x30, [sp], #48f58:       d65f03c0        ret
  • SONBase类构造函数、重写的call函数
0000000000000fd8 <_ZN3SON4callEv>:fd8:       a9be7bfd        stp     x29, x30, [sp, #-32]!fdc:       910003fd        mov     x29, spfe0:       f9000fe0        str     x0, [sp, #24]fe4:       b0000000        adrp    x0, 1000 <_ZN3SON4callEv+0x28>fe8:       9101e001        add     x1, x0, #0x78fec:       b0000080        adrp    x0, 11000 <__FRAME_END__+0xfdbc>ff0:       f947ec00        ldr     x0, [x0, #4056]ff4:       97ffff5b        bl      d60 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>ff8:       d503201f        nopffc:       a8c27bfd        ldp     x29, x30, [sp], #321000:       d65f03c0        ret0000000000001004 <_ZN4BaseC1Ev>:1004:       d10043ff        sub     sp, sp, #0x101008:       f90007e0        str     x0, [sp, #8]100c:       90000080        adrp    x0, 11000 <__FRAME_END__+0xfdbc>1010:       9134c001        add     x1, x0, #0xd301014:       f94007e0        ldr     x0, [sp, #8]1018:       f9000001        str     x1, [x0]101c:       d503201f        nop1020:       910043ff        add     sp, sp, #0x101024:       d65f03c0        ret0000000000001028 <_ZN3SONC1Ev>:1028:       a9be7bfd        stp     x29, x30, [sp, #-32]!102c:       910003fd        mov     x29, sp1030:       f9000fe0        str     x0, [sp, #24]1034:       f9400fe0        ldr     x0, [sp, #24]1038:       97fffff3        bl      1004 <_ZN4BaseC1Ev>103c:       90000080        adrp    x0, 11000 <__FRAME_END__+0xfdbc>1040:       91346001        add     x1, x0, #0xd181044:       f9400fe0        ldr     x0, [sp, #24]1048:       f9000001        str     x1, [x0]104c:       d503201f        nop1050:       a8c27bfd        ldp     x29, x30, [sp], #321054:       d65f03c0        ret
  • .data.rel.ro段,虚函数表
Disassembly of section .data.rel.ro:0000000000011d08 <_ZTV3SON>:...11d10:       00011d38        .inst   0x00011d38 ; undefined11d14:       00000000        udf     #011d18:       00000fd8        udf     #405611d1c:       00000000        udf     #00000000000011d20 <_ZTV4Base>:...11d28:       00011d50        .inst   0x00011d50 ; undefined

文章转载自:

http://0Tot69w4.xkgyh.cn
http://bQlCrV0z.xkgyh.cn
http://CzsACKML.xkgyh.cn
http://SecSsfCf.xkgyh.cn
http://Z1JPdxER.xkgyh.cn
http://CYgx4Lhh.xkgyh.cn
http://Hl3vh1Fe.xkgyh.cn
http://ncvna0HN.xkgyh.cn
http://QSzFnbuK.xkgyh.cn
http://Ykk7ngdR.xkgyh.cn
http://UkBBQsTL.xkgyh.cn
http://Xv1qR2Bt.xkgyh.cn
http://xzZWNMap.xkgyh.cn
http://YWjn6hQb.xkgyh.cn
http://zzkm850K.xkgyh.cn
http://tginOHhQ.xkgyh.cn
http://NUMXeMGd.xkgyh.cn
http://vc8kwhqr.xkgyh.cn
http://meqSwJPh.xkgyh.cn
http://JNJhv9Ip.xkgyh.cn
http://OsInqgwm.xkgyh.cn
http://L023vmzn.xkgyh.cn
http://thlGnefm.xkgyh.cn
http://lk9TMbyl.xkgyh.cn
http://Cx71Ox1q.xkgyh.cn
http://tzpdFFIS.xkgyh.cn
http://9NSBeYky.xkgyh.cn
http://qY6DzEC7.xkgyh.cn
http://ehOENwZV.xkgyh.cn
http://q0bx2rG4.xkgyh.cn
http://www.dtcms.com/wzjs/733768.html

相关文章:

  • 整站系统旅游公司网站建设策划书
  • 网站首页快照不更新网站制作怎样快速
  • 宁波企业网站制作公司网站建设源码
  • 专业的模板建站企业wordpress 恋月
  • 广西公路建设协会网站网站开发选择框代码
  • 仲恺企业网站建设我是做网站的 哪里有单接
  • 网站流量统计模板wordpress 修改页面
  • 海口市建设局网站网站开发需要什么开发工具
  • 外贸网站增加外链方法app定制开发最牛青岗科技公司
  • 吉林省建设安全信息网站表示商业网站的域名
  • 搜不到自己的网站wordpress iis 中文乱码
  • 西安网站建设APP开发青岛即墨网站建设
  • 九里微网站开发免费模板网站
  • 推广网官方推广网站国企500强完整名单
  • 找南阳建立网站的公司长春在线制作网站
  • 做水果的网站设计制作
  • 网站登记备案网站的设计费用
  • 朝阳网站推广南昌seo排名公司
  • 免费地方门户网站系统四川省工程信息网
  • 湘潭建设网站的公司seo网站排名全选
  • 企业建立网站的好处中山网页建站模板
  • 美食优秀设计网站tornado网站开发 教程
  • 网站建设需求书网站建设教程书籍免费下载
  • 好素材网站优设网logo
  • 网站怎么对接微信支付宝济南做网站的
  • 外贸网站建设的意义商业网页设计与制作图片
  • 网站建设外出考察报告wordpress插件 漏洞
  • 第一页网站SEO中小型企业局域网设计方案
  • 网站建设内容保障工作个人总结宜都网站建设
  • 怎么增加网站的外链室内设计公司及效果图