c++ 基础知识笔记

继承

什么是继承 继承就是子类继承父类的成员属性以及方法

继承的本质就是 数据的复制 是编译器帮我们做了很多操作

class Base
{
public:
Base(){
cout << "Base 构造函数"<< endl;
}
~Base(){
cout << "Base 析构函数" << endl;
}
};
class Sub : public Base
{
public:
Sub(){
cout << "Sub 构造函数"<< endl;
}
~Sub(){
cout << "Sub 析构函数"<<endl;
}
};
void Test(){
Sub sub;
cout << sizeof(sub)<<endl;
}



这个时候我们打印出来的 Sub的大小是1

因为它没有任何数据

如果说我们这个时候在Base 和Sub类中各自增加两个int 类型的成员变量 我们再来看看Sub的大小

class Base
{
public:
Base(){
cout << "Base 构造函数"<< endl;
}
~Base(){
cout << "Base 析构函数" << endl;
}
private:
int x;
int y;
};
class Sub : public Base
{
public:
Sub(){
cout << "Sub 构造函数"<< endl;
}
~Sub(){
cout << "Sub 析构函数"<<endl;
}
public:
int a;
int b;
};
void Test(){
Sub sub;
cout << sizeof(sub)<<endl;
}



这个时候我们可以看到结果变成了16

为什么是 16呢 因为Base 与 Sub各自有两个int类型的成员变量 int 类型占用4个字节 所以Sub自己有两个int类型的变量 然后又继承了 Base的 所以这个时候的Sub大小就是 以Base为起始+Sub的大小所以就是16个字节

然后我们在构造函数中给这两个类的各自成员赋上初始值再观察下反汇编的代码





我们仔细看 编译器帮我们分配了 Sub类的临时内存

我们仔细看一下ECX 存储的就是 我们定义的Sub类的首地址

大小 正好是16个字节 目前还未初始化 所以使用CC填充

下面就是直接调用了Sub类的构造函数我们单步进去看看



我们跟到Sub的构造函数中可以很明显的看到 先调用了 基类Base 的构造函数 完成Base的成员初始化

然后再初始化Sub类中自身的成员变量

push        ebp
004018B1 mov ebp,esp
004018B3 push 0FFh
004018B5 push offset __ehhandler$??0Sub@@QAE@XZ (00447599)
004018BA mov eax,fs:[00000000]
004018C0 push eax
004018C1 mov dword ptr fs:[0],esp
004018C8 sub esp,44h
004018CB push ebx
004018CC push esi
004018CD push edi
004018CE push ecx
004018CF lea edi,[ebp-50h]
004018D2 mov ecx,11h
004018D7 mov eax,0CCCCCCCCh
004018DC rep stos dword ptr [edi]
004018DE pop ecx
004018DF mov dword ptr [ebp-10h],ecx
004018E2 mov ecx,dword ptr [ebp-10h]
004018E5 call @ILT+395(Base::Base) (00401190)
004018EA mov dword ptr [ebp-4],0
004018F1 push offset @ILT+215(std::endl) (004010dc)
004018F6 push offset string "Sub \xb9\xb9\xd4\xec\xba\xaf\xca\xfd" (0046e01c)
004018FB push offset std::cout (00479a28)
00401900 call @ILT+665(std::operator<<) (0040129e)
00401905 add esp,8
00401908 mov ecx,eax
0040190A call @ILT+500(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011f9)
0040190F mov eax,dword ptr [ebp-10h]
00401912 mov dword ptr [eax+8],1Eh
00401919 mov ecx,dword ptr [ebp-10h]
0040191C mov dword ptr [ecx+0Ch],28h
00401923 mov dword ptr [ebp-4],0FFFFFFFFh
0040192A mov eax,dword ptr [ebp-10h]
0040192D mov ecx,dword ptr [ebp-0Ch]
00401930 mov dword ptr fs:[0],ecx
00401937 pop edi
00401938 pop esi
00401939 pop ebx
0040193A add esp,50h
0040193D cmp ebp,esp
0040193F call __chkesp (00406f70)
00401944 mov esp,ebp
00401946 pop ebp
00401947 ret

这里还可以很明显的看到 首先用 mov dword ptr [ebp-10h],ecx

把我们定义的Sub类的对象的首地址 存放到了 ebp-10h 的一个临时变量中

然后调用完基类Base的构造函数后

0040190F mov eax,dword ptr [ebp-10h]

00401912 mov dword ptr [eax+8],1Eh

00401919 mov ecx,dword ptr [ebp-10h]

0040191C mov dword ptr [ecx+0Ch],28h

对Sub类中的成员 a 、b分别赋值

mov dword ptr [eax+8],1Eh 这一段 可以 = [this+0x8] = 30

mov dword ptr [ecx+0Ch],28h 这一段 可以 = [this+0xc] = 40

有没有疑问说为什么 a的地址跑到了 this+8的位置了?

其实前8个字节已经被Base中的成员变量占用了

我们可以看看内存中的数据



可以看到 this+0 与 this+4 的位置分别存放了 十进制 的10、20的整数值

而this +8 与 this +0xc 的位置 分别存放了 十进制的 30 、40的整数值

到了这里 大家应该明白了 其实继承就是 数据的复制这个说法了吧 其实就是编译器帮我们自动生成了很多我们看不到的代码

现在看到这里 我提出一个小问题 怎么修改 Base中的x 和y的值呢?



相信聪明的你已经懂了

c++ 基础知识回顾 继承 继承的本质就是数据的copy的更多相关文章

  1. Java基础知识回顾(一):字符串小结

    Java的基础知识回顾之字符串 一.引言 很多人喜欢在前面加入赘述,事实上去技术网站找相关的内容的一般都应当已经对相应知识有一定了解,因此我不再过多赘述字符串到底是什么东西,在官网中已经写得很明确了, ...

  2. C#基础知识回顾-- 反射(1)

    C#基础知识回顾-- 反射(1)   反射(reflection)是一种允许用户获得类型信息的C#特性.术语“反射”源自于它的工作方式: Type对象映射它所代表的底层对象.对Type对象进行查询可以 ...

  3. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  4. C#学习笔记(基础知识回顾)之值类型和引用类型

    一:C#把数据类型分为值类型和引用类型 1.1:从概念上来看,其区别是值类型直接存储值,而引用类型存储对值的引用. 1.2:这两种类型在内存的不同地方,值类型存储在堆栈中,而引用类型存储在托管对上.存 ...

  5. C++ 基础知识回顾总结

    一.前言 为啥要写这篇博客?答:之前学习的C和C++相关的知识,早就被自己忘到一边去了.但是,随着音视频的学习的不断深入,和C/C++打交道的次数越来越多,看代码是没问题的,但是真到自己操刀去写一些代 ...

  6. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

  7. C#基础知识回顾-- 反射(3)

    C#基础知识回顾-- 反射(3)   获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺垫, ...

  8. C#基础知识回顾--线程传参

    C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...

  9. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  10. scrapy实战1,基础知识回顾和虚拟环境准备

        视频地址 https://coding.imooc.com/learn/list/92.html   一. 基础知识回顾     1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...

随机推荐

  1. qt开发ROS gui 遇到:global.h:1087:4: error: #error &quot;You must build your code with position independent code if Qt was built with -reduce-relocations. &quot......

    具体错误如下: 一共出现38个错误 这个错误是在导入cmakelists.txt时产生的,其实不是工程本身的问题,是因为我卸载ros,再重新安装ros的过程中把qtcreator的部分包给删除了,导致 ...

  2. Round #590 (Div. 3)

    拿DIV找快乐... 当场过了A-B1-B2-C 写D差5分钟写的是正解...留坑补FG A. Equalize Prices Again 直接判断sum%n==0?sum/n:sum/n+1 B1, ...

  3. mysql数据库之多表查询

                                                                            准备                          ...

  4. 谷歌BERT预训练源码解析(三):训练过程

    目录前言源码解析主函数自定义模型遮蔽词预测下一句预测规范化数据集前言本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BERT针对两个任务同 ...

  5. PHP内置服务器

    PHP在安装的时候会内置了服务器的功能,我们在使用的过程中如果只是调试,可以选择启动PHP内置的服务器,下面是windows下PHP内置服务器的启动步骤: 1.将php的D:\phpStudy\php ...

  6. 运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs', 原因是

    webpack@3.X运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs' 我的原因是:  web ...

  7. jq常用事件

    https://www.cnblogs.com/sandraryan/ click(); 点击事件 dblclick(); 双击事件 $('.box').dblclick(function(){ al ...

  8. js实现div的碰壁反弹效果

    文章地址 https://www.cnblogs.com/sandraryan/ 需求: 写一个div,让div在父级进行匀速运动,碰到父级上下左右的边框,就向反方向运动. 碰壁反弹在游戏制作中很常用 ...

  9. springboot2多数据源完整示例

    springboot2 + mybatis + mysql + oracle + sqlserver多数据源的配置 相信很多朋友在开发的时候,可能会碰到需要一个项目,配置多个数据源的需求,可能是同一种 ...

  10. PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能

    PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能 网上很多正则表达式只能获取或者替换一个img的src内容,或者只能替换固定的字符串,要动态替换多个图片内容的试了几个小时 ...