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指向的虚函数表中的被重载函数的位置
C++ 编译器的更多相关文章
- python开发编译器
引言 最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便.乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用. ...
- 使用 Roslyn 编译器服务
.NET Core和 .NET 4.6中 的C# 6/7 中的编译器Roslyn 一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为 ...
- 编译器开发系列--Ocelot语言7.中间代码
Ocelot的中间代码是仿照国外编译器相关图书Modern Compiler Implementation 中所使用的名为Tree 的中间代码设计的.顾名思义,Tree 是一种树形结构,其特征是简单, ...
- 编译器开发系列--Ocelot语言1.抽象语法树
从今天开始研究开发自己的编程语言Ocelot,从<自制编译器>出发,然后再自己不断完善功能并优化. 编译器前端简单,就不深入研究了,直接用现成的一款工具叫JavaCC,它可以生成抽象语法树 ...
- 从Unity3D编译器升级聊起Mono
接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...
- 基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)
基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#) 为了完美解析GLSL源码,获取其中的信息(都有哪些in/out/uniform等),我决定做个GLSL编译器的前端(以后简称编译器或 ...
- 在 CSS 预编译器之后:PostCSS
提到css预编译器(css preprocessor),你可能想到Sass.Less以及Stylus.而本文要介绍的PostCSS,正是一个这样的工具:css预编译器可以做到的事,它同样可以做到. “ ...
- 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的
0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...
- Keil> 编译器特有的功能 > 关键字和运算符 > __weak
__weak 此关键字指示编译器弱导出符号. 可以将 __weak 关键字应用于函数和变量声明以及函数定义. 用法 函数和变量声明 对于声明,此存储类指定一个 extern 对象声明,即使不存在,也不 ...
- 明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064
看到“明显调用的表达式前的括号必须具有(指针)函数类型”这句时我才发现我的语文水平有多烂,怎么看都看不懂,折腾了半天才知道是哪里出了问题. 举个简单的例子 class CTest { void (CT ...
随机推荐
- Vue watch用法
Vue.js 提供了一个方法 watch,它用于观察Vue实例上的数据变动.对应一个对象,键是观察表达式,值是对应回调.值也可以是方法名,或者是对象,包含选项. 例如,同一个组件切换时,不会触发生命周 ...
- php+jquery 实现 ajax上传图片到非当前服务器
用 html file控件上传图片,因为 $_FILES["file"] 是传到当前服务器,想要上传到另外一个服务器需要通过服务器脚本实现. 1.图片上传 引入jquery 和 a ...
- 2018数学建模国赛总结(A题/编程选手视角)
2018数学建模已经告一段落了,先说说基本情况吧,我们队伍专业分别为:金融(A),会计(B),计算机(我),配置还算可以,他们俩会数据分析软件也会写论文,我可以写代码,画图.他们俩打过美赛(M奖),我 ...
- Codeforces Round #549 (Div. 2)A. The Doors
A. The Doors time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- c语言指针的简单实例
c语言的指针的存在使得c语言对硬件的操控,以及灵活性得到了极大的提高. 但是指针的使用存在着很多难点问题. #include<stdlib.h> #include<stdio.h&g ...
- 堆排序工具类(适用于top k问题,java泛型实现)
代码如下,作用如标题所述 public class HeapSort { //方法作用:取出list里面的最小的 k 个值 public static <T extends Comparable ...
- 【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 00 目录 遗传算法定义 生 ...
- 根据枚举获取枚举的Description特性值
首先定义一个枚举:两个值:已确认.未确认. public enum ConfirmStatusEnum { [Description("未确认")] unconfirmed = , ...
- 洛谷 P1546 最短网络 Agri-Net(最小生成树)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P1546 首先不难看出这道题的思想是用了最小生成树,但是这道题有难点: 1.读题读不明白 2.不会读入 ...
- EA添加时序图
在项目浏览器的空白处右击 http://blog.csdn.net/craftsman1970/article/details/70877530 不同于大部分面向对象或者UML的书籍,在讨论完类图/对 ...