以下是我于2023年6~7月间换工作时遇到的面试题目,有需要的小伙伴可以参考下。约100个题目。
1 C和C++的区别
1) 文件区别:C源文件后缀 .c;C++源文件后缀 .cpp
2) 返回值: C默认返回int型;C++ 若无返回值,必须指定为void
3) 参数列表:C默认接收多个参数;C++默认为void,不接收任何参数
4) 缺省参数:C不支持给函数参数指定默认值;C++支持
5) C++支持函数重载,C不支持
(而C++支持重载的依仗就在于C++的名字修饰与C不同,例如在C++中函数int fun(int ,int)经过名字修饰之后变为_fun_int_int ,而C是_fun,一般是这样的,所以C++才会支持不同的参数调用不同的函数;)
6) C指针;C++多了引用
7) C是面向过程的,C++是面向对象的。
8) 结构:C中的struct和C++的类,C++的类是C所没有的,但是C中的struct是可以在C++中正常使用的,并且C++对struct进行了进一步的扩展,C语言结构只有成员变量没有成员方法,C++结构有自己的成员变量和成员函数。使struct在C++中可以和class一样当做类使用,struct的成员默认访问修饰符是public,而class默认的是private;
9) 动态管理内存:C是使用malloc/free函数,C++除此之外还有new/delete关键字
10) C++全部变量的默认链接属性是外链接,而C是内连接;
11) C中用const修饰的变量不可以用在定义数组时的大小,但是C++用const修饰的变量可以(如果不进行&,解引用的操作的话,是存放
2 C++特性
继承(保持已有类的特征而构造新类的过程就是继承)
封装(将数据和操作数据的方法绑定在一起)
多态(调用成员函数时,会根据函数调用对象的类型来执行不同的函数)
3 对虚函数是如何实现的多态?
派生类重写父类的虚函数,并且用父类指针或引用去指向派生类的对象。那么在程序运行时就可以实现动态绑定,即实现多态。
4 当以类的对象作为函数参数时,引用、指针和对象它们有什么区别?
作为函数参数时,使用对象指针会产生副本,会带来时间和空间的消耗;
使用对象引用不会产生副本,也不会带来时间和空间的消耗;
引用和指针的相同点: 1. 都是地址的概念; 指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
引用和指针的区别: 1. 指针是一个实体,而引用仅是个别名; 2. 引用使用时无需解引用(*),指针需要解引用; 3. 引用只能在定义时被初始化一次,之后不可变;指针可变; 4. 引用不能为空,指针可以为空
5.说一下虚继承
虚继承是为了解决多重继承而出现的。让某个类做出声明,承诺愿意共享它的基类. 其中,这个被共享的基类就称为虚基类(VirtualBase Class),本例中的 A 就是一个虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。
6.C++有几种继承方式,详细说一下
三种,共有,私有,保护.
不同的继承方式决定了基类成员在派生类中的访问权限
1) public:
基类中的public和protected成员在派生类中仍然保持原有属性;
基类中的private成员在派生类中不能使用。
2) protected
基类中的public和protected成员在派生类中为protected属性;
基类中的private成员在派生类中不能使用;
3) private
基类中的public和protectd成员在派生类中为private属性;
基类中的private成员在派生类中不能使用
7.C和C++类型转换了解不,详细说下
一隐式类型转换
二者都有,包括赋值语句转换、初始化时的转换、表达式中的转换、传参时的转换。
C中
C++中
二强制类型转换
C中,只有(int)这种形式的强制类型转换运算符
C++中,有4个专用的强制类型转换运算符:
dynamic_cast:用于转换类类型
const_cast:用于去除const变量的const属性
static_cast:用于基本类型以及类类型的上下转换
reinterpret_cast:用于执行底层的重新解释类型转换
8.线程有几种同步方式,你在工作中用到哪些?Qt提供了几种同步方式?
线程同步是指同一进程中的多个线程互相协调工作从而达到一致性。
C++线程同步的四种方法:
1) 互斥量
2) 信号量
3) 读写锁
4) 条件变量
9.Qt中,说一下创建线程方式
1)继承QThread
2) 使用moveToThread
3)使用QtConcurrent
4) 使用线程池
11.数组和指针各自有什么优缺点?
1、从空间分配来说:数组是静态分配,指针是动态分配。
2、从访问效率来说:数组是直接访问,指针是间接访问,数组效率要高一点。
3、从安全性来说:数组容易造成越界,而指针会出现野指针造成的内存泄漏。相比之下数组更为安全一点。
4、从函数形参来说:越界传指针用指针的指针,传两位及以上数组用的是数组指针。
5、从处理对象来说:指针偏向于计算机地址的处理,而数组偏向于值的处理。
6、从空间连续性来说:指针分配空间不一定是连续的,而数组对一个的空间一定是里连续的。
1、指针可以直接对硬件进行操作访问,
2、数组的静态分配是比较占内存的,动态分配更为灵活,解决了空间分配利用率的问题。
3、指针访问更为灵活,相较于数组,但是由于它过于灵活,往往不注意就会造成内存泄漏。
16.C和C++中struct
17 C++中的struct和class的区别
1)默认的访问控制属性不同:
struct是public 的,class 是 private 的。
2)继承关系中的默认防控属性不同:
struct是public 的,class 是 private 的。
3)class这个关键字还可用于定义模板参数,strcut不行
18.析构函数可以成为虚函数吗?为什么要用virtual关键修饰析构函数?不修饰行吗?
C++中基类采用virtual虚析构函数是为了防止内存泄漏。
具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。
19.虚函数怎么实现的?
每个虚函数都会有一个与之对应的虚函数表,该虚函数表的实质是一个指针数组,存放的是每一个对象的虚函数入口地址。对于一个派生类来说,他会继承基类的虚函数表同时增加自己的虚函数入口地址,如果派生类重写了基类的虚函数的话,那么继承过来的虚函数入口地址将被派生类的重写虚函数入口地址替代。那么在程序运行时会发生动态绑定,将父类指针绑定到实例化的对象实现多态。
20.重写、重载、覆盖
重写:如派生类对基类中的虚函数进行重新定义,是在不同作用域的;
重载:在同一作用域内写一个函数名相同,但参数列表不同的函数叫做重载。
(重载的函数应该是形参的数量或形参的类型上有所不同,不允许两个函数除了返回类型外其他所有要素都相同)
重定义:也叫作隐藏,子类重新定义父类中具有的相同名称的非虚函数.
21.预编译时,如何避免重复展开头文件
1) #ifndef#endif
2)#pragma once方式