欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 腾讯PC客户端面经

腾讯PC客户端面经

2025/5/18 7:47:23 来源:https://blog.csdn.net/m0_75178021/article/details/147522057  浏览:    关键词:腾讯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.现在又一个文本编译器,要求尽可能的保存用户在编辑器中的数据,因为系统可能随时崩溃,我们又什么办法,将用户的数据保存下来呐?

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

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

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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词