C++面试题整理

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.函数调用过程(堆栈图)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,511评论 1 51
  • 题目类型 a.C++与C差异(1-18) 1.C和C++中struct有什么区别? C没有Protection行为...
    阿面a阅读 7,643评论 0 10
  • 1. C++基础知识点 1.1 有符号类型和无符号类型 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值...
    Mr希灵阅读 17,969评论 3 82
  • 好吧,马上他就六十周岁了。作为他半辈子以来专注培养的“小情人”,我从未写过关于他的只言片语,在他三十几年源源不断的...
    凤歌温心阅读 2,179评论 28 34
  • 在我比现在小几岁的时候,开补习班还没有钱途和前途。 因为父母对我的诸多限制,我并不觉得“金窝银窝比不上自家...
    电锯嘴冻豆腐心阅读 256评论 0 1