c++ 基础知识回顾 继承 继承的本质就是数据的copy

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类的构造函数我们单步进去看看


QQ图片20190914155436.png

我们跟到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中的成员变量占用了
我们可以看看内存中的数据


QQ图片20190914155436.png

可以看到 this+0 与 this+4 的位置分别存放了 十进制 的10、20的整数值
而this +8 与 this +0xc 的位置 分别存放了 十进制的 30 、40的整数值
到了这里 大家应该明白了 其实继承就是 数据的复制这个说法了吧 其实就是编译器帮我们自动生成了很多我们看不到的代码
现在看到这里 我提出一个小问题 怎么修改 Base中的x 和y的值呢?


QQ图片20190914155436.png

相信聪明的你已经懂了
QQ图片20190914155436.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • 程序从入口点 401280 开始执行代码 [esp 28ff8c ebp 28ff94] push ebp [es...
    f675b1a02698阅读 2,269评论 0 3
  • 站在巨人的肩膀上——IDA PRO权威指南阅读笔记 一,窗口 view->open subviews 打开/关闭各...
    SueLyon阅读 14,380评论 0 6
  • 照例把女儿房间的灯打开,让她先醒醒。拉开窗帘,外面漆黑一片。我寻思:今天到底是阴是晴?怎么一点也看不出来? 先生也...
    Sophia安然阅读 1,672评论 6 24
  • 臭咪来家已经三个多月了,之前妄想通过各种方法改变的恶习依然存在,然而我却淡定多了。刚刚发现它长出了新的犬齿,小兔崽...
    荆花香满夏阅读 273评论 1 0
  • 在现代社会,很多人已经,被频繁的工作和事情,被忙得不知所措,却忘记了一种东西,就叫做朋友。现在对朋友的好感...
    安静的刺阅读 221评论 0 1