C++常见面试题总结

1、C和C++的区别
  • C是面向过程的语言,是对一个输入经过一系列的处理得到输出的过程;C++是面向对象的语言,C++最主要的特点是封装、继承和多态;封装,隐藏了实现的细节,使得代码模块化;派生类可以继承父类的数据和方法,扩展已存在的模块,实现了代码的重用;多态则是“一个接口,多个实现”,通过派生类重写父类的虚函数,实现了接口的重用。
  • C和C++中内存的管理方式不一样,C使用的是malloc和free,而C++使用的是new和delete;
  • C++中有引用,而C中没有引用;
2、C++中引用和指针的区别
  • 指针是一个新的变量,存储的是另一个变量的地址,我们可以访问这个地址来修改另一个变量;
  • 引用是一个别名,代表的还是这个变量本身,所以对引用的任何操作就是对变量本身的操作,以达到修改变量的目的;
  • 引用只有一级,而指针可以有多级;
3、struct和class的区别
  • struct可以看成是一个数据结构的实现体;
  • class可以看成是一个对象的实现体;
  • struct的成员和成员函数在默认的情况下访问级别是public;
  • class的成员和成员函数在默认的情况下访问级别是private;
  • C++结构体的继承默认是public,而c++类的继承默认是private
4、#define和const的区别
  • 类型和安全检查不同
    • 宏定义是字符替换,没有数据类型;同时这种替换没有类型安全检查,可能产生边际效应等错误;
    • const是常量的声明,有类型的区别,需要在编译阶段进行类型检查;
  • 编译器处理不同
    • 宏是在预处理阶段展开;
    • const常量是在编译运行阶段展开;
  • 存储方式不同
    • 宏是直接替换,不会分配内存,存储在程序的代码段中;
    • const常量需要进行内存分配,存储在程序的代码段中;
5、C中的 malloc/free 和C++中的 new/delete 有什么区别
  • C++中new/delete是操作符,可以对他进行重载,只能在C++中使用;
  • malloc/free是库函数,可以对他进行重写,在C++和C中均可以使用;
  • new可以调用对象的构造函数,delete可以调用对象的析构函数;
  • malloc和free仅仅可以用来分配内存和回收内存;
6、delete和delete[]的区别
  • 用new申请的内存用delete进行释放;用new[]申请的内存用delete[]进行释放;
  • delete调用一次析构函数;delete[]调用每个成员的析构函数;
7、sizeof和strlen的区别
  • sizeof是操作符,strlen是库函数;
  • sizeof的参数可以是数据类型,也可以是变量;strlen的参数只能是以‘\0‘结尾的字符串;
  • sizeof计算的是数据类型占内存的大小;而strlen计算的是字符串的实际长度;
  • sizeof在编译器编译时就计算出来了,而strlen在函数运行时才计算出来;
8、const解释和作用
  • 如果数据能在一定范围内共享,又希望他不被任意更改,可以使用const,把有关数据定义为常量;常量具有只读特性。
  • const修饰类的数据成员,常数据成员只能通过构造函数的初始化列表,对常数据进行初始化;
  • const修饰类的成员函数,常成员函数只能引用本类中的数据成员,不能修改他们;
  • const修饰类的对象,为常对象,常对象声明的同时,必须初始化;
9 、static解释和作用
  • 在C中static主要用于定义,全局静态变量和局部静态变量;
    • 全局静态变量只在定义它的文件内有效;
    • 局部静态变量只在定义它的函数内有效,只不过程序只给他分配一次内存,函数返回后,变量不消失;
  • 在C++中在此基础上又加了两种,类中的静态数据成员和静态成员函数;
    • 静态数据成员在每个类中只有一个拷贝,由该类的所有对象共同维护和使用,实现数据共享;
    • 静态成员函数可以通过类名或对象名来调用,而非静态成员函数只能通过对象名来调用;

注意:因为 static 定义的变量分配在静态区,所以其定义的变量的默认值为 0,普通变量的默认值为随机数,

10、C和C++ 内存分配

C和C++内存分配方式可以分为三种:

  • 从静态存储区域分配;
    内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。例如,全局变量,静态变量
  • 从栈上分配;
    在执行函数时,函数内部变量的存储单元都在栈上创建,函数执行结束时这些存储单元被自动释放。
  • 从堆上分配;
    即动态内存分配;程序运行期间应用malloc和new申请内存,程序员自己负责何时用free或delete去释放,动态内存的生存周期由程序员局决定。

注意:一个C或C++程序编译时内存分为5大存储区:堆区、栈区、全局区、文字常量区、程序代码区;

11、堆和栈的区别
  • 管理方式不同;堆由程序员控制申请和释放,栈由操作系统自动分配和释放;
  • 空间大小不同;栈的大小要远远小于堆的大小;
  • 生长方向不同;堆的生长方向是向上的,栈的生长方向是向下的;
  • 分配效率不同;栈由系统自动分配,速度较快,堆有人工分配,速度较慢;
  • 分配方式不同;堆是动态分配的,栈有动态和静态两种方式;
  • 栈是连续的,而堆是不连续的;
12、 什么是野指针,如何避免

野指针指没有被初始化的指针,所以不知道指针具体的指向;

“野指针”产生原因及解决办法如下:

  • 指针变量声明时没有被初始化。解决办法:指针声明时初始化,可以是具体的地址值,也可让它指向 NULL。
  • 指针 p 被 free 或者 delete 之后,没有置为 NULL。解决办法:指针指向的内存空间被释放后指针应该指向 NULL。
  • 指针操作超越了变量的作用范围。解决办法:在变量的作用域结束前释放掉变量的地址空间并且让指针指向 NULL。
13、什么是悬空指针

悬空指针指针指向一块内存被释放后,但该指针仍指向该内存;为了避免出现悬空指针,释放后给指针赋为NULL;、

14、什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?

动态分配内存所开辟的空间,在使用完毕后未手动释放,导致一直占据该内存,即为内存泄漏。

方法:malloc/free要配套,对指针赋值的时候应该注意被赋值的指针是否需要释放;使用的时候记得指针的长度,防止越界

15、线程和进程的区别
  • 根本区别:进程是操作系统分配资源的最小单元,线程是操作系统进行运算调度的最小资源;
  • 从属关系不同:进程中包含了线程,线程属于进程;
  • 开销不同:进程的创建、销毁和切换的开销都远大于线程;
  • 拥有资源不同:每个进程有自己的内存和资源,一个进程中的线程会分享这些内存和资源;
  • 控制和影响能力不同:进程的CPU利用率低,线程的CPU利用率高;
  • 操纵者不同:进程的操纵者一般是操作系统,线程的操作者一般是程序员;
16、虚函数、纯虚函数、虚函数列表的介绍
  • 虚函数:C++的类中在成员函数前加上关键字“virtual”这个函数就是虚函数,派生类中对基类中的虚函数进行重写,即实现了多态;
  • 纯虚函数:在虚函数后面加上“=0”,就是纯虚函数,纯虚函数没有函数体,在派生类中对纯虚函数进行重写,就实现了接口的多态;有纯虚函数的类,叫做抽象类;
  • 虚函数列表:当一个类中有虚函数的时候会自动创建一个虚函数列表,虚函数列表中有虚函数指针,列表中存储的是虚函数的地址,当派生类对基类的虚函数进行重载的时候,虚函数列表中派生类的虚函数地址会替代基类中同名的虚函数地址,通过对象调用虚函数,是通过虚函数列表来实现的。

更详细的解释请参照博客:C++ 之多态性、虚函数和纯虚函数

17、C++中RAII机制

RAII,即Resource Acquisition Is Initialization,在初始化中获取资源。
RAII机制,通过在栈上创建临时变量,这样临时变量就接管了堆上内存的控制权,当该临时变量声明周期结束时,则对应的堆上内存自然就被释放了。

RAII 的一般做法是这样的:在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个存放在栈空间上的局部对象。

RAII全称是“Resource Acquisition is Initialization”,直译过来是“资源获取即初始化”,也就是说在构造函数中申请分配资源,在析构函数中释放资源。因为C++的语言机制保证了,当一个对象创建的时候,自动调用构造函数,当对象超出作用域的时候会自动调用析构函数。所以,在RAII的指导下,我们应该使用类来管理资源,将资源和对象的生命周期绑定。

17、什么是智能指针

从比较简单的层面来看,智能指针是RAII(Resource Acquisition Is Initialization,资源获取即初始化)机制对普通指针进行的一层封装。这样使得智能指针的行为动作像一个指针,本质上却是一个对象,这样可以方便管理一个对象的生命周期。

在c++中,智能指针一共定义了4种:
auto_ptr、unique_ptr、shared_ptr 和 weak_ptr。其中,auto_ptr 在 C++11已被摒弃,在C++17中已经移除不可用。

在查询博客时看到有大牛写的博客很好贴出来供大家分享:C/C++面试题分享
C/C++面试题分享「虚函数、多态、内存管理与软件调试篇」

如有错误欢迎指正。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xp_fangfei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值