面试宝典之C++多态灵魂拷问

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

一、重载,隐藏/重定义,覆盖/重写

重载:同一作用域下的同名函数,需要返回值相同,参数列表不同构成重载

重定义/隐藏:继承关系中,子类与父类有同名函数就构成隐藏,只要名字相同,就构成隐藏,同时,析构函数也是特殊的同名函数。因为多态的需要,编译器会把它同一处理为destructor

重写:
重写具有两个条件:一是该函数在父类是虚函数,二是函数相同(返回值,函数名,参数列表),但是对于返回值而言,有特例,叫做重写的协变,具体请看C++中的多态(上),满足以上两个条件就是重写,不满足函数三同,那么虚函数就按普通函数处理,如果虚函数不是拿来完成多态,纯纯资源浪费,因为会创建虚表指针和虚表。

二、多态的原理

多态的原理就是多态调用是运行时决议,虚函数会创建一个虚表指针指向虚表(这个虚表在常量区中,可以通过打印地址看到)多态调用就会去查找虚表中的对应函数。所以子类完成虚函数重写,那么就可以通过父类的指针/引用来完成多态。

三、inline可以是虚函数吗

内联函数是可以为虚函数的,如果内联不是虚函数,那么构成内联的条件的话,在预编译阶段就会展开,不会进符号表,所以在链接的时候找不到定义,所以把内联函数怕的就是这个。但是,inline是建议性的关键字,加了virtual之后,编译器就忽略掉了inline。

四、静态成员函数可以是虚函数吗

①虚函数的调用过程:会先进入函数,因为虚函数是接口继承,所以父和子的接口都一样,随便进入一个,反正多态调用最后都会查虚表,该函数对应的虚表只有这一个,进入函数之后,通过this指针的方式,访问到虚表,从而进行调用,而静态成员函数的一大特点就是没有this指针,所以它也无法去通过多态调用。所以就算把静态成员函数存进虚表,也没有意义
②因为静态成员函数是可以通过指定类域的方式访问的 如A::func(); 说明它是编译时决议,你不管怎么多态,它在编译的时候就确定地址了,所以怎么也不会走到调用虚表这一地步。

五、构造函数可以是虚函数吗

①首先,虚构造函数是没有意义的,因为构造函数的名字和类名相同,所以并不会发生重写,所以构造函数如果是虚函数,只会浪费空间
②虚函数表和虚函数指针是在构造函数的初始化列表进行初始化的,因为构造函数只会在对象创建的时候调用一次,如果你去调用虚构造函数,那么进入构造函数就会调用this,找到虚表指针去查虚表(虚表是编译阶段就确定了的,因为编译器通过识别virtual来创建虚表,存在常量区),但是此时构造函数都还没有构造,虚表指针都找不到
所以构造函数不能是虚函数

六、拷贝构造可以是虚函数吗

①第一点同上,没有意义,浪费资源
②第二点也同上,因为还没有拷贝构造好,你就要调用我的虚表指针,我找不到

七、赋值运算符重载可以是虚函数吗

因为如果已经到赋值运算符重载了,说明对象以及构造好了,所以赋值运算符重载可以是虚函数

八、析构函数可以是虚函数吗

析构函数需要定义成虚函数,这是因为避免内存泄漏。如果不定义成虚函数,那么A*a = new B/A&a = b;(b是new出来的),他们就只能析构父类的部分,而子类新开辟的空间就没有被释放掉,导致内存泄漏,编译器为了能让析构函数完成重写,函数名会同一处理成destructor,然后调用的时候,只需调用子类的析构就可以了(父类的析构会在子类的析构之后自动调用,细节见C++中的多态(上)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪皮兄弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值