C++ || 继承与多态(详细笔记)

10 篇文章 0 订阅

【1】继承

继承的本质

继承的本质就是代码的复用

1.继承的访问限定?

在这里插入图片描述

2.派生类怎么初始化从基类继承来的成员?

通过调用基类相应的构造函数进行初始化,派生类只会初始化自己的成员。

3. 构造析构的顺序?

先构造基类部分 再构造派生类部分 析构时先析构派生类对象 再析构析构基类方法

4.继承结构是从上到下的结构

默认支持从下到上的转换
基类对象=》派生类对象 ------------ 不可以 ----------上到下
派生类对象=》基类对象 ------------ 可以 -------------下到上
基类指针/引用=》派生类对象 ----- 可以 - -----------下到上
派生类指针/引用=》基类对象 ------不可以 ----------上到下

【2】多态

1.什么是多态?

静态多态:函数重载和模板(编译期的绑定)
动态多态:call 虚函数 实际 call 寄存器eax 不确定(运行时的绑定)

2.多态的好处

通过基类指针指向派生类对象 调用派生类的同名覆盖方法 基类指针指向哪个对象 就调用哪个派生类的虚函数表中的方法

3.重载 隐藏 覆盖(基类和派生类同名成员函数之间的关系)

重载:
函数名相同 参数列表不同 同一个作用域

隐藏:
处在基类和派生类中 函数名相同就可以

覆盖:
基类和派生类当中 函数的返回值 函数名 参数列表都相同 而且基类的函数是virtual虚函数 称作覆盖关系(虚函数表的覆盖)

4.请解释静态绑定(编译)(函数调用)和动态绑定(运行)?

静态类型:对象在声明时采用的类型,在编译期既已确定;
动态类型:通常是指一个指针或引用目前所指对象的类型,是在运行期决定的;
静态绑定 直接绑定函数的地址 绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
动态绑定 绑定虚函数表 寄存器 绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期 运行时确定

5.vfptr vftable 什么时候生成?运行时加载到那一块内存??

如果一个函数有虚函数 那么在编译阶段该类型会产生一个对应的虚函数表 存虚函数的地址 运行时加载到全局的数据段

类的大小为成员对象内存加上虚函数指针的内存大小
虚函数指针指向虚函数表的起始地址
继承的时候会继承过去虚函数 产生派生类的对象时 也会产生虚函数表 覆盖掉原来的虚函数表

6.RTTI指针

RTTI指针存储在虚函数表vftable当中,指向一段类型字符串 运行时的类型信息

7.虚函数表

存的内容:运行时的类型信息RTTI 偏移量 虚函数的地址
存在的前提:此时已经有对象 对象可以取地址

8. 抽象类

凡是含有纯虚函数的类叫做抽象类 例:virtual void fun() = 0;
这种类不能定义对象,只是作为基类为派生类服务,但可以定义指针或引用。
除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。在派生类实现该纯虚函数后,定义抽象类对象的指针,并指向或引用子类对象。

9.虚函数的缺省参数(重点)

虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。

class A
{
public:
    virtual void Fun(int number = 10)
    {
        std::cout << "A:: with number " << number<<endl;
    }
};
 
class B: public A
{
public:
    virtual void Fun(int number = 20)
    { 
        std::cout << "B:: with number " << number<<endl;
    }
};

int main()
{
    B b;
    A &a = b;
    b.Fun();
    a.Fun();
}

代码运行如下
在这里插入图片描述
从结果可以看到因为缺省参数属于静态绑定
所以当b->Display() 默认的参数是10;d->Display() 默认的参数是20 这是我们不愿意看到的。
在使用虚函数的时候,一定要考虑号缺省参数的问题。

【3】继承和多态的常见笔试题的分析

1.能不能成为虚函数=》记录函数地址(vftrbles)/vfptr (地址)
答:必须有对象已经存在 而且可以取地址

2.析构函数能不能实现成virtual虚析构函数?
答:可以的,此时已经有对象的存在

3.构造函数能不能实现成virtual虚构造函数?
答:不可以 因为这时候还没有对象

4.在构造函数中调用virtual虚函数,请问是静态绑定还是动态绑定?
答:静态绑定 因为此时没有产生对象 动态绑定依赖于对象 此时不能访问对象的前四个字节RTTI。

5.在析构函数中调用virtual虚函数,请问是静态绑定还是动态绑定?
答:是动态绑定,此时已经有对象的存在了。

6.static静态成员方法可不可以写成虚函数?
答:不可以 他的调用不依赖对象的存在

7.inline内联函数可不可以写成虚函数?
答:C++11新标准 已经可以写成虚函数 加virtual之后变成普通函数。

8.什么时候析构函数必须写成虚析构函数?
答:基类指针(引用)指向堆上派生类的的资源时,此时要把析构函数写成虚析构函数。

9.调用虚函数一定会发生动态绑定么?
不一定 对象的直接调用虚函数 永远是静态绑定
而指针或者引用调用虚函数的话才会发生动态绑定。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值