C++学习篇(1)

更多精彩请关注微信公众号“爱折腾的码农”,二维码见下图。
在这里插入图片描述

本篇主要是写c++三大特性:封装、继承、多态的知识点,其中封装是为了实现代码模块化;继承是为了实现代码复用;多态是为了实现接口重用。下面分别详细说这三部分。

  • 封装(数据、接口、实现)

        1、类在实现过程中把数据的定义和操作放在类的内部,对外仅提供接口,这样将实现细节隐藏在类内部,对外不可见;

        2、通过封装可以让使用使用者只关心对象提供的接口,而无需了解具体实现方式,有效地做到了信息隐藏,提高程序的安全性,并且类内部的改动不会影响外部的使用,提高了程序的可维护性。

图片

     通过子类继承父类已有的特性,在无需重复实现同样功能的前提下扩展自身的新功能, 解决了代码复用的问题,这种模式大大提高了开发效率。

    分类:公有继承、保护继承、私有继承;也可分单一继承和多继承,这部分在动态多态部分讲述。

  • 继承(public、protected、private)

      出现的问题:对于继承来说,会出现菱形继承(定义:多个类继承自同一公共基类,而这些派生类又被同一个类继承),如下图所示,现有基类Base,其中A和B继承自Base,但是C有继承自A,B,因此C产生的对象模型中会出现两份Base,因此会出现数据冗余和二义性的问题。

图片

        为了解决数据冗余和二义性的问题,引入了虚继承的概念。如上右图所示,引入virtual关键字。这样在类A和B中只保存了偏移地址,个人理解应该是有虚函数指针,这样将Base中数据保存至一个公共区域,这样解决了数据冗余和二义性的问题。

 

  • 多态(静态多态、动态多态)

        对于多态来说,首先要理解重载和覆盖(重写)的区别。

       重载:在同一作用域下,函数名相同,但是函数形参列表不同,包括形参个数、形参类型不同,除此之外,const放在函数名后面也可以实现重载,如下图所示。原理:c++底层的重命名机制,将函数形参类型作为函数名的后缀,这就是为什么C++中写c语言代码需要加“extern”的原因之一。

图片      

      覆盖(重写):在子类继承父类中,前提是父类中定义了虚函数,若子类中对虚函数进行重新实现,则在子类虚函数表中该虚函数地址改为修改后的虚函数地址。一般需使用virtual关键字,其强调在不同作用域下的子类和父类。

 

        下面来介绍静态多态和动态多态

        静态多态:通过重载实现的,包括函数重载、运算符重载等;

        动态多态:通过虚函数实现(有普通虚函数、纯虚函数,纯虚函数是为了父类定义接口,子类继承后提供具体的实现),需要virtual关键字,运行时通过基类指针指向派生类对象。

    对于拥有虚函数类而定义的对象来说,每个对象都会拥有虚函数指针,但是会同一个虚函数表。当生成对象时,会在对象起始位置放置一个虚表指针,用来调用虚函数表中的虚函数。

 

虚函数对象模型

 

  • 虚函数表:存在常量存储区,属于只读存储段,即代码段,包括了类中所有虚函数的地址,按照声明的顺序排列。
  • 虚函数指针:每个类对象都有一个虚函数指针,当利用一个基类的指针绑定基类或派生类对象时,程序运行时调用某个虚函数成员,会根据对象的类型去初始化该虚函数指针,实现动态绑定。

     接下来我会分析虚函数对象模型,如果面试问到虚函数的话可以说这部分,如有疑问可以看《深度探索C++对象模型》这本书,我也是主要从这本书里面总结的,有专门的一章写这个。

    虚表指针(vptr)的位置(头部或尾端):

单一继承和多重继承

 

虚函数带来的问题:1、明显的增加了空间负担;2、打断了与c程序间的链接性。

  • 放置尾端的好处:可以保留基类的对象布局
  • 放在头部的好处:在多重继承下,通过指向类成员的指针调用虚函数会带来一些帮助。否则,对于放在尾端的话需要计算offset。但是他也丧失了c语言的兼容性。

 

  • 单一继承:在子类的内存空间中,首先会继承父类的虚函数表,若在子类中定义了不存在的虚函数,则会放置在父类虚函数的后面。
  • 多重继承:在子类中的每个父类都有虚函数表,因此会有多个虚函数指针,子类中定义不存在的虚函数则放在第一个父类的表中。

1、若单一继承且无虚函数,其内存布局如下,根据声明顺序存放。

图片

 2、若单一继承且含有虚函数,其中虚函数指针可放在头部或尾部,由编译器决定,一般是放在头部。

图片图片

3、多重继承

图片

图片

4、虚继承

    

图片

5、虚继承下的继承类中带有虚函数(可不看,面试回答前4个就可以了)

图片

      总结:在面试过程中,对于c++三大特性方面问的其实挺多的,但是万变不离其宗,回答问题要找到自己的亮点,比如说面试官问c++的多态特性,那么可以说静态多态实现原理(重载定义和原理:重命名机制等等)、动态多态实现原理(虚函数)、分析单一继承和多继承下的内存模型、虚函数指针在头部和尾端的优劣等等。其实很多的人都只是看面经,但是如果想提升自己的竞争力,一定要去看底层原理或者源码,多总结问题的答案,如果有疑问的话,可以去掘金、CSDN这样的技术网站找答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值