当前位置: 首页 > ds >正文

腾讯PC客户端面经

1.有关虚函数调用问题

空指针可以在特定的情况下去调用非虚函数,因为非虚函数在编译阶段就可以确定地址,调用的时候this指针传的是nullptr没有问题,不需要依赖对象的创建。

空指针不可以去调用虚函数,因为虚函数的调用需要虚表,对象通过虚表指针才能找到虚表,虚表指针的初始化是在构造函数中进行的,根据上面的推理链,nullptr不会创建对象,没有调用构造函数,所以虚表指针没有被复制,找不到虚表,故无法调用虚函数。

#include <iostream>using namespace std;class A
{
public:void func(){cout << "1" << endl;cout << a_ << endl;}virtual void v_func(){cout << "2" << endl;}
private:int a_;
};
int main()
{A* ptr = nullptr;/* <空指针调用非虚函数>* 非虚函数在编译阶段就已经确定了函数的地址,不依赖于对象的实例(这个对象是否被创建)。* 编译器把成员函数调用转换为普通函数 A::func(ptr), 对象的地址作为隐含参数传递过去 nullptr* 但是这种空指针访问非虚函数的方式仍然存在极大的风险,例如如果在函数内部调用了成员变量,回造成* 空指针访问的问题*/ptr->func();/* <空指针调用虚函数>* 虚函数的调用需要虚表, 每个类都有一个虚表,但是类有多个对象,每个对象都有一个虚表指针存储虚函数的* 地址从而找到虚表,虚表指针是在构造函数中赋值的,那么就存在一个问题,如果是空指针那么并没有创建* 对象的实例,没有办法去调用构造函数,也就没有办法给虚表指针赋值,找不到虚表也就无法调用虚函数*/ptr->v_func();return 0;
}

2.创建一个类,编译器会默认提供哪些函数?

C++98

默认构造、默认析构、默认拷贝构造、默认赋值运算符重载

C++11

默认移动构造、默认移动运算符重载

C++11后,如果自定义了的析构函数,系统将不会提供默认移动构造 、移动赋值

3.string类型在构造函数中赋值和初始化参数列表中初始化的区别

首先明确一个调用顺序问题,是先调用初始化参数列表,给成员变量进行初始化,如果没在初始化参数列表中的成员变量会调用它们的默认构造。然后是进入构造函数的函数体中,对成员变量进行赋值。

比如string举例,如果在初始化参数列表中,会调用string类的特定构造函数进行初始化。

但是如果在构造函数中赋值,需要先调用stirng类的默认构造进行默认初始化,然后再进行赋值,效率会低很多。

4.菱形继承中,各个类的虚函数表有什么变化

比如现在有A B C D四个类,A类是B、C的基类,D类多继承于B类、C类。满足菱形继承关系。

假设现在A中有一个func1函数,且是虚函数。

B、C、D中分别重载了该函数

A:A::func1

B:B::func1

C: C::func1

D: 两个虚表,一个从B继承而来,一个从C继承而来。

5.虚继承如何解决菱形继承二义性问题的

A、B、C、D。

那么虚继承指的是,B类C类虚继承于A,A作为虚基类。此时BC继承过来的不再是A中的变量,而是一个虚基表指针,里面存储着虚基表的地址,虚基表里面存折虚基表指针到A类中成员地址的偏移量。故通过虚基表指针 + 偏移量就可以找到虚基类的成员变量

这样D类在继承的时候,有两份虚基表指针,无论是使用B的,还是使用C的找到的都是唯一的成员变量。不会产生二义性问题啦

6.C++中四种类型转换

static_cast【提供的是编译器认为安全的类型转换】

基本数据类型之间的转换

向上转换

dynamic_cast

向下转换

这个过程会有安全检查,具体是如何检查的呐,方法如下:

1.检查该对象是否有虚函数,如果没有虚函数,就找不到虚表,无法通过RTTI找到对象的实际类型信息

2.获取对象的实际类型信息

3.比较实际类型信息于目标类型信息,如果是一样的,转换成功

如果目标类型信息是实际类型信息的基类,也是转换成功的

其他情况返回一个nullptr指针

const_cast

去常转换

通常用于指针或者引用

const int a = 10

const_cast(a) false

7.weak_ptr在lock,获取shared_ptr的时候,怎么判断是否获取成功?

lock函数核心是去获取所引用的shared_ptr的引用计数,如果发现引用计数 > 0,说明托管的对象还在,反之说明托管的对象已经被释放了,那么lock函数返回一个空就好了

8.STL-deque底层的数据结构是什么?

一个指针数组 + 若干个固定大小的缓冲区

MAP_SIZE = 2

QUEUE_SIZE 4096 / sizeof(T)

9.现在又一个文本编译器,要求尽可能的保存用户在编辑器中的数据,因为系统可能随时崩溃,我们又什么办法,将用户的数据保存下来呐?

定时自动保存:起一个定时器

实时保存:没输入一个字符,或者进行一次编译的时候,都去进行一个保存操作

增量保存:只保存用户对文本所做的增量修改,而不是整个文本内容。这样可以减少保存的数据量,提高保存效率。

备份文件:除了正常保存的文件外,定期创建备份文件。备份文件可以保存到不同的磁盘分区或外部存储设备,以防止本地磁盘故障导致数据丢失。

http://www.xdnf.cn/news/2101.html

相关文章:

  • Tailwind CSS实战:快速构建定制化UI的新思路
  • 无线通信网
  • 面向对象编程核心:封装、继承、多态与 static 关键字深度解析
  • 汽车售后 D - PDU 和 J2543 详细介绍
  • 【GCC bug】libstdc++.so.6: version `GLIBCXX_3.4.29‘ not found
  • ISCTF2024-misc(部分)
  • JavaScript学习教程,从入门到精通,Ajax数据交换格式与跨域处理(26)
  • GitHub Copilot (Gen-AI) 很有用,但不是很好
  • Object.defineProperty 与 Proxy解析
  • 【OpenGL】聚光灯照明 Assignment | 5.3.7.Tiger Shading PS SC BL GLSL
  • 汽车行业EDI教程——北美X12标准 需求分析及方案
  • 【EDA】EDA中聚类(Clustering)和划分(Partitioning)的应用场景
  • React类组件与React Hooks写法对比
  • Float32、Float16、BFloat16
  • 【KWDB 创作者计划】_深度学习篇---数据获取
  • 一篇速成Linux 设置位 S(SetUID)
  • 欧拉计划 Project Euler56(幂的数字和)题解
  • SAP ABAP S/4新语法
  • python代做推荐系统深度学习知识图谱c#代码代编神经网络算法创新
  • ai聊天流式响应,阻塞式和流式响应 nginx遇到的坑
  • c#加密证件号的中间部分,改为*号
  • Flask 请求数据获取方法详解
  • 信息学奥赛一本通 1509:【例 1】Intervals | OpenJudge 百练 1201:Intervals
  • NLP高频面试题(五十四)——深度学习归一化详解
  • 使用npm install或cnpm install报错解决
  • 鼠标指定范围内随机点击
  • websheet之 编辑器
  • PyTorch与CUDA的关系
  • Android——Activity与Fragment通信
  • Asp.Net Core 异常筛选器ExceptionFilter