美文网首页C++面试
C++面试题整理

C++面试题整理

作者: 猿哥媛姐 | 来源:发表于2018-03-15 09:14 被阅读181次

1.数组名和指针的区别?

明确一点数组名不是指针,可以通过sizeof来验证。其本质是指代数组这样一个数据结构。

数组名在表现很像const指针指针,不可以被改变(被赋值,++,--),可以用*来取对象,作为指针参数,可以+整数

做为形参的数组名失去了其数据结构的本质内涵,其本质是一个指针。

2.引用类型和指针的区别

从反汇编的角度看,引用的本质是一个由编译器管理的指针。其表现出来的语法特征和其所引用的对象一致。

作为函数参数时,和指针一样,真正传递的是指针,而非对象的拷贝,较少了堆栈空间的使用,而且可以在函数体内可以对所指的对象进行修改。

引用不可以被修改,以失去了指针的灵活性为代价,提高了程序安全性。

3.const总结

const的作用是希望通过对指定const属性,保证变量不被错误修改,提高代码的安全性。

修饰变量:变成了常量,不可以被修改,其他操作不受影响。编译器在编译时将用到该变量的地方替换成对应的值。与#define的替换相比,const保留了变量的类型属性,可以做类型检验。

修饰指针:作用在指针本身,则该指针不能被修改(const指针),所以必须初始化;作用在其指向的对象上,则不能通过该指针修改其指向的对象;绑定常量的引用必须是指向常量的引用,指向常量的引用绑定的未必是常量。

修饰引用:不能够通过该引用修改其绑定的对象。绑定常量的引用必须是指向常量的引用,指向常量的引用绑定的未必是常量。

修饰函数:修饰隐式的this指针,将this指针设置为指向常量的指针,所以不能在函数体内修改数据成员。

4.new/delete和malloc/free的区别

new/delete最终调用malloc/free来申请和释放内存。

c++封装了new和delete完成为对象分配内存,调用构造函数,调用析构函数,释放内存工作。

使用上比malloc和free更加方便,不用指定大小;引入异常bad_alloc。

new和delete通过调用operator new和operator delete来分配和释放内存, 而这两个函数可以重载,为程序员自己实现内存管理提供了方便。

5 struct和class的区别

在功能上基本没有什么区别,class能做到事情struct基本能做。struct可以有成员函数,可以继承,可以有虚函数(实现多态)。

区别在于默认的访问控制:

6.const和define的区别

处理阶段:const在编译运行阶段使用,define在编译预处理阶段展开

存储方式:const需要分配内存来存储常量,而define不用分配内存

安全性:编译器会对const做类型检查更加安全。

作用域:默认情况下const的作用范围是文件内部,多个文件共享需要使用extend ,#define的作用范围是全局,多个文件定义define同名会报错。

7.const和static的区别

内存区域:

8.const和static在类中使用的注意事项

static成员不属于任何对象,而是被他们共享。

静态数据成员应该在类的外部定义。

因为没有this指针,static成员函数不能用const修饰,也不能访问非静态成员。

9.c++内存管理

10.内联函数

将函数指定为内联函数(inline),调用位置上内联展开,避免函数调用的开销(堆栈维护,调整指令)。应用在规模小,流程直接,频繁调用的函数。

将代码放在符号表里,在调用点上展开。

内联说明只是向编译器发出一个请求,编译器可以忽略这个请求。编译器优化时,也可能将没有inline说明的函数展开成内联函数。

11.多态和虚函数

C++通过虚函数实现动态绑定,也就是多态。

动态绑定是根据对象本身,而不是指针或引用的类型来确定具体调用的函数。具体实现是在对象中维护一个虚函数表指针,同个虚函数表中存储了对象调用的函数的指针。

虚函数通过虚函数指针和虚函数表来实现动态绑定。

编译器编译时,为每个有虚函数的类生成一个虚函数表(一个一维数组),用来存储该类的虚函数地址。

编译器为每个对象提供一个指向虚表的指针。(在32位机器的内存上看,是其前4个字节,这也是为什么有虚函数的类型的sizeof多4个字节的原因)。

指向虚表的指针的初始化在构造函数中进行。

虚函数的位置,按照先后顺序排列。

子类复制一份父类的虚函数表,替换重写的虚函数地址,新加的虚函数依此放在表尾。

12.C++中的重载和重写的区别:

重载:名称相同参数不同。对操作相识的函数,用相同的名字,方便程序员的理解,减轻起名字,记名字的负担。

重写:同名同参数,虚函数,子类将父类覆盖掉(在虚函数表中覆盖掉),即使通过强制类型转化也不能访问(对指针和引用而言)。

重定义:同名(参数可同可不同),基类中的函数被隐藏,子类对象无法直接访问。

13.面向对象的三个特征

继承,多态,封装。

继承:本质是代码复制。

多态:多态和虚函数

封装:将数据和和对操作封装到放在一起。

14.析构函数一般写成虚函数的原因 

delete父类指针时,可以调用对像真正的析构函数。否则可能会出错,如子类中有指针类型,并且申请了内存,这时就会造成内存泄漏。

15.构造函数为什么一般不定义为虚函数

析构函数通过虚表来调用的,而指向虚表的指针是在构造函数中初始化的,这是个矛盾。

16.构造函数或者析构函数中调用虚函数会怎样

结果上来看和调用普通函数无异。即基类调用基类的虚函数,派生类调用派生类的虚函数。

17.纯虚函数

18.引用是否能实现动态绑定,为什么引用可以实现

引用和指针的静态类型和动态类型可以不一样。

静态类型:变量声明时的类型或表达式生成的类型。编译时已经知道。

动态类型:变量或表达式表示的内存的对象的类型。

19.深拷贝和浅拷贝的区别(举例说明深拷贝的安全性)

在有指针成员的情况下,浅拷贝只是将指针指向已存在的内存。即两个对象的指针成员指向的是同一内存区域。

深拷贝的做法是申请一个内存复制一份,并将新对象指针指向备份区。

安全性:浅拷贝如果修改了指针指向的内容,将对两个对象都有影响。

20.对象复用的了解,零拷贝的了解

对象池:对象池通过对象复用的方式来避免重复创建对象,它会事先创建一定数量的对象放到池中,当用户需要创建对象的时候,直接从对象池中获取即可,用完对象之后再放回到对象池中,以便复用。

适用性:类的实例可重用。类的实例化过程开销较大。类的实例化的频率较高。

零拷贝:emplace_back

21.什么情况下会调用拷贝构造函数

(1)用类的一个对象去初始化另一个对象时

(2)当函数的形参是类的对象时(也就是值传递时),如果是引用传递则不会调用

(3)当函数的返回值是类的对象或引用时

22.结构体内存对齐方式和为什么要进行内存对齐?

23.内存泄露的定义,如何检测与避免?

申请的堆没有被释放,该内存不能在被利用。

24.手写实现智能指针类

25.调试程序的方法

26.C++的四种强制转换(C++不是类型安全的)

static_cast , dynamic_cast , const_cast , reinterpret_cast

static_cast:可以实现C++中内置基本数据类型之间的相互转换。

const_cast: 操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

reinterpret_cast:有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。

dynamic_cast:1)运行时处理,类型检查;2)不能用于内置的基本数据类型的强制转换;3)转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL(指针类型,如果是应用类型,抛出bad_cast异常);4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过;5)

27.遇到coredump要怎么调试

28.调试程序的方法

29.模板的用法与适用场景

模板是C++泛型编程的基础。

使用:template  //关键字+<模板参数列表>

非类型模板参数:

应用场景:除了参数类型不一样外,其他的内容全部一样(函数体),用模板,而不是每一个类型都写一个函数。

特化:模板的一个独立的定义,其中一个或多个参数被指定为特定的类型。通用模板不能适应所有情况。(特殊情况特殊处理)

30.成员初始化列表的概念,为什么用成员初始化列表会快一些

概念:以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式,对成员进行初始化。

效率:构造函数之前执行默认初始化。而成员初始化列表,可以立即初始化,所以更快些。

成员是const对象和引用必须初始化。

31.虚继承

为了避免一个类多次集成一个基类而包含多份基类的拷贝,使用虚继承机制。(基于多重继承)

32.函数调用过程(堆栈图)

相关文章

  • Java基础知识与面试题整理

    # Java基础知识与面试题整理(一) @[toc] ---- ---- ## 垃圾回收机制 传统C/C++等编程...

  • C++基础

    c++面试题

  • C++面试题整理

    C++基础部分 C++ static_cast和dynamic_cast的区别 static_cast可以部分的做...

  • C++面试题整理

    1.数组名和指针的区别? 明确一点数组名不是指针,可以通过sizeof来验证。其本质是指代数组这样一个数据结构。数...

  • C++面试题目整理

    lc#xxx表示在LeetCode上有该问题,序号为xxx。(长期更新中。。。) 编码题 单链表逆置(lc#206...

  • 2017 Android 面试题分享整理

    第174期:2017 Android 面试题分享整理 深度讨论 2017 Android 面试题分享整理 (欢迎评...

  • 面试题

    关注的面试题文集 Android面试题整理 Android工程师面试题大全 Android 面试题总结之Andro...

  • 日记-2020-07-27

    早上:学习vim中午:休息白天: 配合测试 修改批量查询bug 整理面试题-多线程2 整理面试题-JVM部分 待完成

  • Android面试总结二

    参考文章 40个Android面试题Java面试题集Android名企面试题及知识点整理Android面试题收集较...

  • 经典面试100题 - 持续更新中

    打算整理100道经典面试题,整理出来的链接都会附录在下面。 经典面试题1:图片占多少内存经典面试题2:时针和分针经...

网友评论

    本文标题:C++面试题整理

    本文链接:https://www.haomeiwen.com/subject/hwyonxtx.html