面试题八股文之C++补充

本文探讨了C++中的内存对齐规则,包括有效对齐值和对齐规则,并举例说明。接着介绍了哈希表的渐进式rehash过程,阐述其分而治之的优势。此外,讨论了虚函数可以是内联函数的情况及其限制,并提到了内存泄露检测工具Valgrind。最后,对比了push_back和emplace_back在向vector插入元素时的区别,以及模板特例化的概念和用法。
摘要由CSDN通过智能技术生成

内存对齐:
在这里插入图片描述
对齐规则:
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。
有效对其值:是给定值#pragma pack(n)和结构体中最长数据类型长度中较小的那个。有效对齐值也叫对齐单位。
了解了上面的概念后,我们现在可以来看看内存对齐需要遵循的规则:
(1) 结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。
(2) 结构体的总大小为 有效对齐值 的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

例如,对于上个例子的三个结构体,如果前面加上#pragma pack(1),那么此时有效对齐值为1字节,此时根据对齐规则,不难看出成员是连续存放的,三个结构体的大小都是6字节。
在这里插入图片描述

渐进式哈希:
以下是哈希表渐进式 rehash 的详细步骤:
(1)为 ht[1] 分配空间, 让字典同时持有 ht[0] 和 ht[1] 两个哈希表。
(2)在字典中维持一个索引计数器变量 rehashidx , 并将它的值设置为 0 , 表示 rehash 工作正式开始。
(3)在 rehash 进行期间, 每次对字典执行添加、删除、查找或者更新操作时, 程序除了执行指定的操作以外, 还会顺带将 ht[0] 哈希表在 rehashidx 索引上的所有键值对 rehash 到 ht[1] , 当 rehash 工作完成之后, 程序将 rehashidx 属性的值增一。
(4)随着字典操作的不断执行, 最终在某个时间点上, ht[0] 的所有键值对都会被 rehash 至 ht[1] , 这时程序将 rehashidx 属性的值设为 -1 , 表示 rehash 操作已完成。
渐进式 rehash 的好处在于它采取分而治之的方式, 将 rehash 键值对所需的计算工作均滩到对字典的每个添加、删除、查找和更新操作上, 从而避免了集中式 rehash 而带来的庞大计算量。
开始:
在这里插入图片描述
过程中:
在这里插入图片描述
最后:
在这里插入图片描述

虚函数是否可以是内联函数:
答案:虚函数可以是内联函数,内联是可以修饰虚函数的,但是当虚函数表现多态性的时候不能内联。
理由如下:内联是在发生在编译期间,编译器会自主选择内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因此虚函数表现为多态性时(运行期)不可以内联。 inline virtual唯一可以内联的时候是:编译器知道所调用的对象是哪个类(如 Base::who()),这只有在编译器具有实际对象而不是对象的指针或引用时才会发生。

#include <iostream>  
using namespace std;
class Base
{
   
public:
   inline virtual void who()
   {
   
   	cout << "I am Base\n";
   }
   virtual ~Base() {
   }
};
class Derived : public Base
{
   
public:
   inline void who()  // 不写inline时隐式内联
   {
   
   	cout << "I am Derived\n";
   }
};

int main()
{
   
   // 此处的虚函数 who(),是通过类(Base)的具体对象(b)来调用的,
   // 编译期间就能确定了,所以它可以是内联的,但最终是否内联取决于编译器。 
   Base b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值