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

C++ 编译器

C++编译器

  • 当我们定义了一个类的时候, C++编译器在默认的情况下会为我们添加默认的构造方法, 拷贝构造方法, 析构函数和=运算符
  • 在第一次创建对象的语句中如: MyString myString = "hello, world!";中, 如果我们定义的构造函数为如下, 则就是隐式调用构造方法, 如果构造方法使用了explicit修饰则会报错, 总之在第一次创建对象的语句中, 就算出现了=, 只能调用构造方法, 而不是=方法, 因为我们是要构造对象, =真正起作用是在这个对象创建完毕之后

MyString(const char *str="") {
    this->len = strlen(str);
    this->values = new char[this->len + 1];
    strcpy(this->values, str);
}

C++中的对象在内存中的分布

没有继承的情况下

  • 就是一个结构体的分布

单继承的情况下(方法使用virtual修饰)

  • A为基类, B为派生类, 在创建B的实例的时候, 在内存中B的内存中会有一个虚指针(virt_pa)指向一个虚函数表, 注意是一个虚指针(virt_pa), 默认先拷贝A中的虚函数表, 如果B中有新的虚函数则注册到这个表中, 若B中重载了A中的虚函数, 则将虚函数表中的那个对应的虚函数改成B的虚函数(这就是实现多态的关键)

在多继承的情况下(方法都是用virtual修饰)

  • A和B为C的基类
  • 和单继承类似, 只不过多出了一个虚指针(virt_pb), 这个虚指针对应的虚函数表在C对象创建的时候会自动拷贝B的虚函数表, 而另外一个虚指针(virt_pa)指向的虚函数表则拷贝A的虚函数表, 接着在看C类中定义的函数, 如果C中出现了新的虚函数, 则将这个虚函数放到C第一个继承的基类在C对象中对应的虚指针指向的虚函数表中, 这里指的就是A, 也就是所B中多出来的foo函数的地址会放到virt_pa指向的虚函数表中, 如果C重载了函数, 则判断是重载了哪个函数, 这个函数从哪个基类中继承过来的, 知道了是从哪个基类中继承过来的, 就可以通过对应的虚指针找到被重载的函数在虚函数表中的位置, 将其替换成C中重载了的函数, 比如, A中有一个foo函数, C中也有一个foo函数, 则编译器会通过virt_pa指针在对应的表中将C::foo的地址替换到A::foo所在的位置

多重单继承

  • A -> B -> C
  • 和单继承非常的类似, 也是只有一个指针, 这个指针为virt_pa, 可以知道是超级基类的, 在创建C对象的时候, 将A和B中的虚函数表拷贝到C中的virt_pa对应的虚函数表中, 在考虑重载

虚继承

  • A -> B
  • 虚继承与上面的继承最大的不同就是在创建了B对象的时候, 会有两个虚指针, 一个是virt_pa, 另外一个是virt_pb, 多出来一个与B相关的指针; 除此之外, virt_pb指向的虚函数表只保存B类中定义的所有的虚函数, 如果B重载了A中的某一个方法, 则就会将B中那个函数的指针拷贝到virp_pa指向的虚函数表中的被重载函数的位置

相关文章:

  • Haskell写的Parser
  • Java String.getBytes()编码
  • smm架构的优势
  • 不学无数——SpringBoot入门Ⅲ
  • 比特币的暴跌史
  • 微信小程序直播,腾讯云直播+微信小程序实现实时直播
  • POI导出数据以Excel的方式录入,下载
  • 如何实现MetaMask签名授权后DAPP一键登录功能?
  • 双十一流量洪峰 支撑阿里核心业务的云数据库揭秘
  • python编程入门----测试与类编写
  • 项目(八) Jenkins持续集成与构建
  • Dashboard安装配置
  • vue中的slot
  • String和StringBuilder、StringBuffer的区别?
  • 关于Numba开源库(Python语法代码加速处理,看过一个例子,速度可提高6倍)
  • Angular4 模板式表单用法以及验证
  • classpath对获取配置文件的影响
  • Git同步原始仓库到Fork仓库中
  • Intervention/image 图片处理扩展包的安装和使用
  • JavaScript 一些 DOM 的知识点
  • JavaScript新鲜事·第5期
  • jQuery(一)
  • Linux中的硬链接与软链接
  • Vue实战(四)登录/注册页的实现
  • Windows Containers 大冒险: 容器网络
  • zookeeper系列(七)实战分布式命名服务
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 码农张的Bug人生 - 见面之礼
  • 使用API自动生成工具优化前端工作流
  • 一个JAVA程序员成长之路分享
  • 回归生活:清理微信公众号
  • 整理一些计算机基础知识!
  • ​如何在iOS手机上查看应用日志
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (33)STM32——485实验笔记
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (离散数学)逻辑连接词
  • (三)终结任务
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Unity3DUnity3D在android下调试
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .Net程序帮助文档制作
  • .NET上SQLite的连接
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [.net]官方水晶报表的使用以演示下载
  • [c语言]小课堂 day2
  • [HackMyVM]靶场 Quick3
  • [LeetCode]Max Points on a Line
  • [LeetCode]—Permutations 求全排列
  • [LeetCode]—Permutations II 求全排列(有重复值)