C++常见面试问题总结 for the job(持续更新)

1.new和delete是如何实现的,与malloc和free的异同

new操作在处理数据时,分为两种情况:
(1)简单数据类型(包括基本数据类型和不需要构造函数的类型):整型、字符型、浮点型。
. 直接调用operator new分配内存;
. 可以通过new_handler来处理new失败的情况;
. new分配失败的时候不像malloc那样返回NULL,它会直接抛出异常bad_alloc。要判断是否分配成功应该采用异常捕获的机制;
(2)复杂数据类型(需要由构造函数初始化对象):构造类型:枚举、数组、结构体等
. new复杂数据类型的时候先调用operator new,然后在分配的内存上调用构造函数。
delete同样分为两种情况:
(1)简单数据类型(同上)
. delete简单数据类型时默认只调用free函数。
(2)复杂数据类型
. delete复杂数据类型时先调用析构函数再调用operator delete
三 与malloc和free的区别:**
(1)属性上:new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要C的头文件支持。
(2)参数:使用new操作符无需指定内存块的大小,编译器自动计算。但是malloc需要显示地指出所需内存的尺寸。
(3)返回类型:new操作符内存分配成功时,返回的是对象类型的指针。malloc内存成功分配时,返回的是void*,需要通过类型转换将其转换为我们需要的类型。
(4)重载:C++允许重载new/delete操作符。malloc为库函数不允许重载。

2.什么是智能指针?智能指针的原理是什么?

. 智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,程序结束自动释放。
. 将基本类型的指针封装为类对象指针,同时在析构函数里编写delete语句删除指针指向的内存空间。
. 不能将指针直接赋值给一个智能指针,一个是类,一个是指针。
. 智能指针的作用:方便管理堆内存。使用普通指针容易造成堆内存泄露。

3.指针和引用的区别

(1)指针是一个新的变量,存储了另一个变量的地址,可以通过访问地址来修改变量。
引用只是一个别名,还是变量本身,对引用的任何操作就是对变量本身进行操作,以达到修改变量的目的。
(2)引用只有一级,而指针可以有多级。
(3)指针传参是值传递。引用传参时传进来的是变量本身。

4.delete和delete[]的区别

. delete只会调用一次析构函数,而delete[]会调用每个成员的析构函数。
. 用new分配的内存用delete释放,用new[]分配的内存用delete[]释放。

5.STL库的内容有?

. STL包括两部分内容:容器(序列式容器和关联式容器)和算法。
. 序列式容器:比如vector,list,queue,stack,heap,slist。
. 关联式容器:比如map,set,hashtable,hash_set。
. 算法包括排序,复制等。

6.const的作用

. const修饰类的成员变量,表示常量不可能被修改。
. const修饰类的成员函数,表示该函数不会修改类中的数据成员。
. const函数只能调用const函数,非const函数可以调用const函数。

7.虚函数的实现

. 虚函数就是用virtual修饰的成员函数。虚函数的作用就是实现多态性。
. 每一个含有虚函数的类都至少有一个与之对应的虚函数表,其中存放着该类所有虚函数对应的函数指针。
. 以下函数不能是虚函数:构造函数;内联函数;静态函数;友元函数。
. 虚函数与纯虚函数的区别:(1)纯虚函数只有定义,没有实现,虚函数既有定义,又有实现。(2)含有纯虚函数的类不能定义对象,含有虚函数的类可以定义对象。

8.C++中struct与class的区别

. 内部默认访问属性:struct默认的是public,而class默认的是private。
. class作为关键字还可以定义模板参数,与typename作用相同。但是struct不能定义模板参数。

9.深拷贝和浅拷贝的区别

. 如果一个类拥有资源,当这个类的对象发生复制过程时,如果资源重新分配了就是深拷贝;反之没有重新分配资源就是浅拷贝。

10.重载overload,覆盖override,重写overwrite三者之间的区别

(1)overload,将语义相近的几个函数用同一个名字表示,但是参数列表不同,这就是函数重载,返回值类型可以不同。
特征:同一个类中,函数名字相同,参数不同,virtual关键字可有可无。
(2)override,派生类覆盖基类的虚函数,实现接口的重用,返回值类型必须相同。
特征:基类和派生类,函数名字相同,参数相同,基类中必须有virtual关键字。
(3)overwrite,派生类屏蔽了其他同名的基类函数,返回值类型可以不同。
特征:基类和派生类,函数名字相同,参数不同或者参数相同且无virtual关键字。

11.友元函数和友元类

. 友元提供了不同类的成员函数之间、类的成员函数和一般函数之间进行数据共享的机制。
通过友元,一个不同函数或者另一个类中的成员函数可以访问类中的私有成员和保护成员。
. 友元的正确使用能提高程序的运行效率,但是同时也破坏了类的封装性和数据的隐藏性,导致数据可维护性变差。
(1)友元函数
. 友元函数是可以访问类的私有成员的非成员函数。它是定义在类外的普通函数,不属于任何类,但是需要在类的定义中声明。
friend类型 函数名(形式参数):一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
(2)友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
friend class类名;
. 友元关系不能被继承。
. 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
. 友元关系不具有传递性。若类B是类A的友元,类C是类B的友元。类C不一定是类A的友元。

12.C++中内存泄露的几种情况

. 内存泄漏是指已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等结果。
(1)类的构造函数和析构函数中new和delete没有配套。
(2)在释放对象数组时没有使用delete[],使用了delete。
(3)没有将基类的析构函数定义为虚函数,当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确释放,因此造成内存泄漏。
(4)没有正确的清楚嵌套的对象指针。

13.静态绑定和动态绑定介绍

. 静态绑定和动态绑定是C++多态性的一种特性。
(1)对象的静态类型和动态类型:
. 静态类型:对象在声明时采用的类型,在编译时确定。
. 动态类型:当前对象所指的类型,在运行时决定,对象的动态类型可变,静态类型无法变化。
(2)静态绑定和动态绑定
. 静态绑定:绑定的是对象的静态类型,在编译时确定。
. 动态绑定:绑定的是对象的动态类型,在运行时确定。
. 只有虚函数才使用的是动态绑定,其他全部是静态绑定。
. 引用或指针也可以实现动态绑定,因为二者的指向对象类型也可以是动态类型。

14.指针和引用的区别?

(1)指针有自己的一块空间,而引用只是一个别名。
(2)指针可以初始化为NULL,但是引用的话必须初始化。
(3)指针可以指向其他对象,但是引用只能是一个对象的引用。
(4)指针可以是多级,但是引用的话没有分级。
(5)当返回动态分配内存的对象时,必须使用指针,引用可能引起内存泄漏(明白了刷leetcode时为啥那么多含指针的参)

15.堆栈的区别?

(1)堆栈空间分配的区别:
. 栈:由操作系统自动分配释放。
. 堆:程序员分配释放。
(2)缓存方式区别:
. 栈:存储值类型,大小固定,超出则会报错,内存溢出。
. 堆:存储引用数据类型,大小不确定。
(3)数据结构上的区别:
. 栈:先进后出的数据结构。
. 堆:类似树结构。

16.C++中四个默认的函数

(1)构造函数:先基类后派生类。
(2)拷贝函数:对象被创建时调用。
(3)析构函数:每个类只有一个析构函数。
(4)赋值函数:每个类只有一个赋值函数。

17.简述左值引用和右值引用的区别

(1)可以取地址、有名字的就是左值;不能取地址、没有名字的就是右值。
(2)左值可以被赋值,右值不可以被赋值。
(3)左值可变,右值不可变。
(4)左值引用和右值引用都能避免对象的拷贝和改变。右值引用改变一个右值时没有意义,左值引用改变左值是有意义的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值