C++面试——进阶篇
2021/9/11 20:07:00
本文主要是介绍C++面试——进阶篇,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、什么情况下会调用拷贝构造函数
- 用类的一个对象去初始化另一个对象的时候: new Object{obj}
- 对一个类对象初始时进行赋值操作:Object newObj = obj;
- 当函数的参数是类的对象时,就是值传递的时候 : void func(Object obj)
- 当函数的返回值是类的对象或者引用的时候 : Object getObject()
注意:编译开了RVO(返回值优化)时,3 和 4 可能并不会发生!
2、 左值和右值的区分
最简单的判断方式:左值有名字,右值没有名字!
int a = 1;// a为左值, 1为右值
如果一个右值有了名字,就会变成左值!比如右值当作形参传递时。
3、编译器默认会生成哪些函数
- 默认构造函数
- 析构函数
- 拷贝构造函数
- 拷贝赋值函数
注意:如果自己定义了有参构造函数,编译器不会再生成默认构造函数
4、 重载overload覆盖override重写overwrite这三者之间的区别
- overload,将语义相近的几个函数用同一个名字表示,但是参数和返回值不同,这就是函数重载(相同范围里函数名字相同、参数不同)
- override,派生类覆盖基类的虚函数,实现接口的重用(基类和派生类中函数名字相同、参数相同、基类函数为虚函数)
- overwrite,派生类屏蔽了其同名的基类函数(基类和派生类中函数名字相同、参数相同、基类函数不是虚函数)
5、什么是接口类,以及接口类的作用
接口类主要用来实现继承时定义相关接口的,是对子类的约束!
一个类中有纯虚函数即为接口类(也叫纯虚类),接口类只能被继承,无法实例化!
6、如何防止类被实例化,这种类的意义是什么
- 添加一个无用的纯虚方法
- 构造函数设置为非public
- 删除构造函数
意义:
- 定义一些算法类、工具类,一般此类中的方法为static方法
- 实现自己内存管理机制(例如通过static方法、友元函数来创建对象)
- 定义接口
7、介绍下友元的特性
- 友元关系不能被继承。
- 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
- 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
- 友元函数的定义默认是扩展到外部的
8、内存对齐的原理于意义
结构体以及类成员属性的字节对齐,意义就是减少cpu读取的次数,提高程序运行效率。比如一个int变量长度为4个字节,cpu一次读4个字节,当然是一次读取比较好。
但是如果前面有一个char,地址为0-1。那么这个int的地址就为1-4。导致cpu,分两次读取int值。
如果要取消字节对齐,使用#pragma pack(1),也就是使用1字节对齐!(一般在网络传输时取消对齐)
9、构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?
构造函数不能声明为虚函数
- 因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的。而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等等
- 虚函数的调用需要虚函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数即构造函数了
析构函数最好声明为虚函数
- 首先析构函数可以为虚函数,当析构一个指向派生类的基类指针时,最好将基类的析构函数声明为虚函数,否则可以存在内存泄露的问题。
- 如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除指向派生类的基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。
10、引用作为函数参数以及返回值的好处及注意事项
引用传参的好处:
- 在函数内部可以对此参数进行修改
- 提高函数调用和运行的效率(所以没有了传值和生成副本的时间和空间消耗)
注意事项:
- 不能返回局部变量的引用。因为函数返回以后局部变量就会被销毁
- 不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一 个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak
- 可以返回类成员的引用,但是最好是const。因为如果其他对象可以获得该属性的非常量的引用,那么对该属性的单纯赋值就会破坏业务规则的完整性。
11、为什么推荐使用auto关键字
- 避免忘记初始化,未初始化的对象可能会导致难以预见的错误!(例如auto x;无法编译通过)
- 避免不必要的代码书写,甚至能帮你避免错误的类型转换!
- 重构代码更简单!(例如 int x = 1; 改为long long x = 123LL; 使用auto 则不需要修改类型)
12、constexpr VS const
- 假如你将一个成员函数标记为constexpr,则顺带也将它标记为了const。
- constexpr是编译时常量(可以作为元编程中的元数据),const是运行时常量
- constexpr函数被应用在调用宏的所有场合。例如,你想要一个计算数组size的函数,size是10的倍数。如果不用constexpr,你需要创建一个宏或者使用模板,因为你不能用函数的返回值去声明数组的大小。但是用constexpr,你就可以调用一个constexpr函数去声明一个数组。
- if constexpr 可以用来做条件编译
13、引用与指针有什么区别
- 引用必须被初始化,指针不必。
- 引用初始化以后不能被改变,指针可以改变所指的对象。
- 不存在指向空值的引用,但是存在指向空值的指针。
14、explicit关键字
- 规避可被单参调用的构造函数引起的隐式类型转换
- 所有的智能指针类都有一个explicit构造函数,以指针作为参数.因此不能自动将指针转换为智能
- 指针对象,必须显式调用
未完,不定时补充。。。。
这篇关于C++面试——进阶篇的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-10Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势
- 2025-01-03用LangChain构建会检索和搜索的智能聊天机器人指南
- 2025-01-03图像文字理解,OCR、大模型还是多模态模型?PalliGema2在QLoRA技术上的微调与应用