多态(C++)

一、(1)编译时(静态)  函数重载,函数模板

(2)运行时(动态)    重点

二、多态的定义及实现

1.构成条件

多态是一个继承关系下的类对象,去调用同一函数,产生不同的行为

1.1必须重要条件

a.必须是基类(父类)的指针或引用调用函数

b.被调用的函数必须是虚函数

其中基类的virtual可以不写,但是不建议,而且这也是考试的埋坑处

1.2虚函数的重写/覆盖:基类中有一个跟派生类完全相同的虚函数(即返回值类型,函数名字,参数列表(指类型int,char...))也称三同

接下来我们看一道知道答案想给面试官背后来个板砖的题

这里按照常规思路,调用test(),而父子类func构成多态(与参数的值无关,类型相同即可),

那么大部分人都会觉得是A->1,这就调到的出题人的坑里,这就考验大家在平时对于细节的掌握,其实构成多态是形成如下的函数

由于大部分例子都是参数的值也相等,所有大部分人会忽略这个细节,所有答案其实是B->1.

那如果是这呢

这里是子类的指针,所以不构成多态,故只是函数的调用

对了

当B的指针传入test中时,是A* this这也是大家需要注意的地方。

1.3协变

派生类重写基类函数时,与基类函数返回值类型不同,即基类的虚函数返回基类的指针或引用,而派生类返回派生类的指针或引用。

协变意义不大,不建议使用

1.4析构函数的重写

基类的析构函数为虚函数,此时派生类析构函数只需要定义,无论是否加virtual,虽不符合重写的规则,实际上编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor,故基类加virtual,就构成了重写。如果~A()不加virtual,那么delete p时,只调用A的析构,没有调用B的析构,导致内存泄漏,这是因为~B()在释放资源。

这里有两次A的析构的原因在继承中我们已经详细讲解过了,子类会自动调用父类的析构

所以这里建议基类的析构设计成虚函数

1.5override和find

在派生类重写后面加override,用来检查函数名是否相同,如果我们不想让派生类重写这个虚函数,用final修饰

1.6相同函数名之间的关系

再看一道例题

答案是12,只要有虚函数,就需要考虑虚表指针(独立),其在32位下是4字节,64位下是8字节

2、纯虚函数和抽象类

在虚函数后面加上=0,不需要定义实现,只要声明即可。包含虚函数的类叫做抽象类,抽象类不能实例化出对象

3、虚函数表

1>基类对象的虚函数表中存放所有虚函数的地址

2>派生类由两部分构成,继承下来的基类和自己的成员,一般情况下,继承下来的基类中有虚函数表指针,自己就不会再生成虚函数表指针。但是要注意的是这里继承下来的基类部分虚函数表指针和基类对象的虚函数表指针不是同一个,就想基类对象成员和派生类对象中的基类对象成员也独立

3>派生类中重写的基类的虚函数,派生类的虚函数就会被覆盖为派生类重写的虚函数地址

4>派生类的虚函数表中包含:基类的虚函数地址,派生类重写的虚函数地址,派生类自己的虚函数地址

5>虚函数表本质是一个存虚函数指针的指针数组

6>虚函数和普通函数一样,编译好后是一段指令,都是存在代码段的,只是虚函数的地址又存到了虚表中

7>C++标准中并没有严格规定虚函数表存在在哪

4、静态绑定和动态绑定

a.对不满足多态条件(指针或引用+调用虚函数)的函数调用是在编译时绑定,也就是编译时确定调用函数的地址,叫做静态绑定

b.满足多态条件的函数调用是在运行绑定,也就是在运行时指向对象的虚函数表中找到调用函数的地址,也叫做动态绑定

Read more

《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

前引:这是一个聚焦基础搜索引擎核心工作流的实操项目,基于 C/C++ 技术生态落地:从全网爬虫抓取网页资源,到服务器端完成 “去标签 - 数据清洗 - 索引构建” 的预处理,再通过 HTTP 服务接收客户端请求、检索索引并拼接结果页返回 —— 完整覆盖了轻量级搜索引擎的端到端逻辑。项目采用 C++11、STL、Boost 等核心技术栈,搭配 CentOS 7 云服务器 + GCC 编译环境(或 VS 系列开发工具)部署,既适配后端工程的性能需求,也能通过可选的前端技术(HTML5/JS 等)优化用户交互,是理解搜索引擎底层原理与 C++ 工程实践的典型案例 目录 【一】Jieba分词工具 【二】正/倒排索引结构设计

By Ne0inhk
【C++指南】类和对象(十):const成员函数

【C++指南】类和对象(十):const成员函数

💓 博客主页:倔强的石头的ZEEKLOG主页             📝Gitee主页:倔强的石头的gitee主页             ⏩ 文章专栏:《C++指南》                                   期待您的关注 目录 引言 一、const成员函数的定义与语法 1. 基本语法 2. 底层原理 二、const成员函数的作用与约束 1. 保障数据安全 2. 与const对象的关系 三、特殊场景与进阶技巧 1. mutable关键字 2. 函数重载 3. 权限传递规则 四、最佳实践与常见误区 1. 编码规范建议 2. 易错点分析 五、总结 引言 在C++中,const成员函数是面向对象编程中保障数据安全性的重要机制。它通过限制函数对类成员的修改权限,提升代码的健壮性和可维护性。 本文将结合代码示例,从语法、原理到实际应用场景,全面解析const成员函数的核心要点。   一、const成员函数的定义与语法

By Ne0inhk
【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: C++的两个参考文档  老朋友(非官方文档):cplusplus 官方文档(同步更新):C++ 官方参考文档 set和multiset的参考文档:set、multiset map和multimap的参考文档:map、multimap unordered_set和unordered_multiset的参考文档:unordered_set、unordered_multiset unordered_map和unordered_multimap的参考文档: unordered_map、unordered_

By Ne0inhk