- 阐述如何设计一个 C++类?实现 String 类。
- 谈谈对 C++虚函数机制的理解。
- STL 的 Vector 原理及迭代器失效的理解。
- 设计一个 C++HashMap 类。
- 使用 C++实现一个堆的模板类。
- 写一个宏定义比较函数并解释宏展开过程。
- 谈谈 std::move 的理解和使用。
- malloc 的内存可以用 delete 释放吗?原因?
- 简述 C++11 的新特性以及解决了什么问题。
- STL 的 Map 原理、插入和删除复杂度分析。
- STL 的 Map 基于红黑树实现的原因,为什么不选择哈希表?
- 为什么需要虚析构?虚析构和普通析构函数的区别是什么?
- 说明 C++对象的内存布局模型。
- 聊聊 C++临时对象和右值引用,写个例子。
- 使用 C++写一个高效的多维矩阵乘法。
- 谈谈对智能指针的认识并实现一个智能指针类。
- STL 中 Map 的查找时[]和 find 区别是什么?哪个更快?
- 实现 memcpy 函数效率尽可能高。
- 尝试实现 C/C++中常用字符串库函数。
- 谈谈 C++中强制类型转换的原理和使用,写个例子。
- 谈谈 C++的设计模式,重点介绍下单例模式、工程模式等。
常用组件
- 常用的 MQ 有哪些以及各自的对比和场景
- Kafka 的基本原理和实现要点
- libevent/libuv 的基本原理和使用
- Boost.Asio 的原理和使用
- 微信协程库 libco 原理和使用
- DPDK 的基本原理和用户态协议栈的概念
- Redis 和 Memcached 对比
- RPC 框架对比:brpc/grpc/thrift
- STL 源码的理解和阅读分析
- Nginx 的架构、原理、使用
虚函数存在哪的?虚表存在哪的?
答:虚表存的是虚函数指针,不是虚函数,虚函数和普通函数一样的,都是存在代码段的,只是他的指针又存到了虚表中。另外 对象中存的不是虚表,存的是虚表指针。
虚函数表本质是一个存虚函数指针的指针数组,这个数组最后面放了一个 nullptr。
总结一下派生类的虚表生成:
a.先将基类中的虚表内容拷贝一份到派生类虚表中
b.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数
c.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后。
多态的实现原理
多态的实现分为静态多态(函数重载)和动态多态(虚函数重写)的实现。
1、静态多态主要是同名函数的重载,在编译的时候就已经确定。编译器会根据函数实参的类型(可能会进行隐式类型转换),来确定具体调用哪个函数,如果有对应的函数就调用该函数,否则会出现编译错误。
2、动态多态主要是父子类同名函数的覆盖,运行时的多态,是用虚函数机制实现的,在运行期间动态绑定。编译器在编译的时候,会为每个包含虚函数的类创建一个虚表和虚表指针。该表是一个一维数组,在虚表中存放了每个虚函数的地址。程序运行时,会根据对象的实际类型来初始化虚表指针,让虚表指针指向所属类的虚表。在调用虚函数的时候,能够根据函数地址找到正确的函数。
举个例子:一个父类的指针指向一个子类对象,使用父类的指针去调用子类中重写了的父类中的虚函数的时候,会调用子类重写过后的函数,在父类中声明为加了 virtual 关键字的函数,在子类中重写的时候不需要加 virtual 也是虚函数。
这里简要介绍一下虚函数的实现原理:
虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数的时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。【虚函数表是每个对象实例共享的,虚函数指针是每个对象实例都有一个。