后端开发面经汇总:C++语言篇

整理后端开发面经的C++语言篇部分,持续整理中…

学习书籍:C++ Primer , 《Effective C++》 等…


C++面经

      • Python和C++的区别?
      • C 和 C++ 的区别?
      • new和delete是如何实现的,new与malloc的异同处?
      • 既然有了malloc/free,C++中为什么还需要new/delete呢?
      • delete和delete[]的区别?
      • 堆和栈有什么区别?
      • 堆快一点还是栈快一点?
      • 指针和引用的区别?
      • 在函数参数传递的时候,什么时候使用指针,什么时候使用引用?
      • C++的四种强制转换:static_cast, dynamic_cast, const_cast, reinterpred_cast


Python和C++的区别?

包括但不限于:

  1. Python是一种脚本语言,是解释执行的;而C++是编译语言,是需要编译后在特定平台运行的。Python可以很方便的跨平台,但是效率没有C++高;
  2. Python的库函数比C++的多,调用起来很方便;
  3. Python使用缩进来区分不同的代码块,C++使用花括号来区分;
  4. C++中需要事先定义变量的类型,而Python不需要。Python的基本数据类型只有数字,布尔值,字符串,列表,元组等;

C 和 C++ 的区别?

包括但不限于:

  1. C是面向过程的语言,C++是面向对象的语言,C++有“封装,继承和多态”的特性。封装隐藏了实现细节,使得代码模块化;继承通过子类继承父类的方法和属性,实现了代码重用;多态则是“一个接口,多个实现”,通过子类重写父类的虚函数,实现了接口重用;
  2. C和C++内存管理的方法不一样:C使用malloc/free,C++除此之外还用new/delete;
  3. C++中还有函数重载引用等概念,C中没有;

new和delete是如何实现的,new与malloc的异同处?

实现:在new一个对象的时候,首先会调用malloc为对象分配内存空间,然后调用对象的构造函数。
delete会调用对象的析构函数,然后调用free回收内存。

异同之处:new与malloc都会分配空间,但是new还会调用对象的构造函数进行初始化,malloc需要给定空间大小,而new只需要对象名;


既然有了malloc/free,C++中为什么还需要new/delete呢?

malloc/free和new/delete都是用来申请内存和回收内存的。

在对非基本数据类型的对象使用的时候,对象创建的时候还需要执行构造函数,销毁的时候要执行析构函数
malloc/free是库函数,是已经编译的代码,所以不能把构造函数和析构函数的功能强加给malloc/free。


delete和delete[]的区别?

  • delete只调用一次析构函数,而delete[]会调用每个成员的析构函数;

  • 用new分配的内存用delete释放,用new[]分配的内存用delete[]释放;


堆和栈有什么区别?

  • 从定义上:堆是由new和malloc开辟的一块内存,由程序员手动管理;栈是编译器自动管理的内存,存放函数的参数和局部变量;
  • 堆空间因为会有频繁的分配释放操作,会产生内存碎片
  • 堆的生长空间向上,地址越来越大,栈的生长空间向下,地址越来越小;

堆快一点还是栈快一点?

栈快一点
因为操作系统会在底层对栈提供支持,会分配专门的寄存器存放栈的地址,栈的入栈出栈操作也十分简单,并且有专门的指令执行,所以栈的效率比较高也比较快。而堆的操作是由C/C++函数库提供的,在分配堆内存的时候需要一定的算法寻找合适大小的内存。并且获取堆的内容需要两次访问,第一次访问指针,第二次根据指针保存的地址访问内存,因此堆比较慢。


指针和引用的区别?

  1. 指针是一个新的变量,指向另一个变量的地址,我们可以通过访问这个地址来修改另一个变量;而引用是一个别名,对引用的操作就是对变量的本身进行操作;
  2. 指针可以有多级,引用只有一级;
  3. 传参的时候,使用指针的话需要解引用才能对参数进行修改,而使用引用可以直接对参数进行修改;
  4. 指针的大小一般是4个字节,引用的大小取决于被引用对象的大小;
  5. 指针可以为空,引用不可以;

在函数参数传递的时候,什么时候使用指针,什么时候使用引用?

  1. 需要返回函数内局部变量的内存的时候用指针。使用指针传参需要开辟内存,用完要记得释放指针,不然会内存泄漏。而返回局部变量的引用是没有意义的;
  2. 栈空间大小比较敏感(比如递归)的时候使用引用。使用引用传递不需要创建临时变量,开销要更小;
  3. 类对象作为参数传递的时候使用引用,这是C++类对象传递的标准方式;

C++的四种强制转换:static_cast, dynamic_cast, const_cast, reinterpred_cast

C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

C++标准库提供了四种强制类型转换形式:static_cast、const_cast、dynamic_cast、reinterpret_cast.每一种适用于特定的场合。

static_cast 用于各种隐式转换。具体的说,就是用于各种基本数据类型之间的转换,比如把int换成char,float换成int等。以及派生类(子类)的指针转换成基类(父类)指针的转换。
特性与要点

  1. 它没有运行时类型检查,所以是有安全隐患的;
  2. 在派生类指针转换到基类指针时,是没有任何问题的,在基类指针转换到派生类指针的时候,会有安全问题;
  3. static_cast不能转换const,volatile等属性;

dynamic_cast 用于动态类型转换。具体的说,就是在基类指针到派生类指针,或者派生类到基类指针的转换。
特性与要点:

  1. dynamic_cast能够提供运行时类型检查,只用于含有虚函数的类;
  2. dynamic_cast如果不能转换返回NULL。

const_cast 用于去除const常量属性,使其可以修改。也就是说,原本定义为const的变量在定义后就不能进行修改的,但是使用const_cast操作之后,可以通过这个指针或变量进行修改; 另外还有volatile属性的转换。

reinterpret_cast 几乎什么都可以转,用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换等。但是不够安全。

你可能感兴趣的:(C++,c++,编程语言,指针,多态)