c++相关面试题

1、new、delete、malloc、free的关系
delete与new对应会调用对象的析构函数,free只会释放内存,new调用构造函数。malloc与free是c++/语言的标准库函数,new、delete是c++的运算符。他们都可以用来申请动态内存和释放内存,对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求,对象在创建的时候要自动执行构造函数,消亡时要执行析构函数。由于malloc和free是库函数而不是运算符,不在编译器的控制权限内,不能够把执行构造函数/析构函数的任务强加于malloc/free。所以c++需要一个能完成动态内存分配和初始化工作的运算符new和一个能完成清理与释放内存工作的运算符delete。
2、delete与delete[]的区别
delete之后调用一次析构函数,而delete[]会调用每个成员的析构函数。
delete和new配套,delete[]和new[]配套,对于内建的简单类型,delete和delete[]的作用是相同的,而对于自定义的复杂数据类型,delete和delete[]不能互用
3、c++有哪些性质
封装、继承、多态
4、比较优秀的c/c++开源框架
STL:C++标准模板库,是一个具有工业强度的,高效的c++程序库,提供非常实用的容器和算法
ASL:由Adobe提供,经过同行评审和可移植的C++源代码库。
Boost:c++准标准库,由c++标准委员会,库工作组发起的,开源、跨平台,作为标准库的后备,是c++标准化进程的开发引擎之一
Folly:由Facebook开发,为实用性和效率设计的开源C++库,类似stl和boost功能的底层库
MFC:微软基础库,以C++类的形式封装了Windows API,包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量的Windows句柄封装类和很多Windows的内建控件和组件的封装类(封装了很多Windows内建控件、组件和句柄)
Qt:由Qt公司开发的跨平台C++图形用户界面应用程序开发框架。也可以用于开发非GUI程序,比如控制台工具和服务器
GTK+:用于创建图形用户界面的跨平台工具包。
JUCE:包罗万象的C++库,用于开发跨平台软件库
Dlib:非常牛逼的c++人脸识别框架
Loki:与《c++设计新思维》一书配套发行的c++代码库,不仅把c++模板的功能发挥到了极致,而且把类似设计模式*这样思想层面的东西通过库来提供
Neu:c++11框架,编程语言集,用于创建人工智能应用程序的多用途软件系统
Opus:一个完全开放的,免版费的,高度通用的音频编解码器。
bzip2:一个完全免费的,免费专利和高质量的数据压缩。
Bolt:针对GPU进行优化的C++模板库。
Bcrypt:一个跨平台的文件加密工具,加密文件可移植到所有支持的操作系统和处理器中。
SQLite:一个完全嵌入的,功能齐全的关系数据库,只有几百kb,可以正确包含在你的项目中
Catch:一个很时尚的,C++原生框架,只包含头文件,用于单元测试,测试驱动开发和行为驱动开发
Cocos2d-x:一个跨平台框架,用于构建2D游戏,互动图书,演示和其他图形应用程序。
Cairo:支持多种输出设备的2D图形库
OpenCV:开源计算机视觉库
WebSocket++:基于C++/Boost Aiso的websocket 客户端/服务器库。
5、子类析构时要调用父类的析构方法吗?
调用,先调用派生类的析构函数,再调用基类析构函数,这与构造函数的调用顺序相反。
6、多态、虚函数、纯虚函数
多态:对不同对象,接收相同消息时产生不同的动作。c++多态性具体体现在编译和运行两个方面:编译时,多态性体现在函数和运算符的重载上;在运行时,多态性通过继承和虚函数上。
虚函数:在基类中冠以关键字virtual的成员函数。它提供了一种接口界面。允许在派生类中基类的虚函数重新定义(此时为重写)
纯虚函数:纯虚函数的存在是为了给子类保留一个函数名字,作为函数接口存在,纯虚函数不具备函数功能,一般不能直接调用。
从基类继承来的纯虚函数,在派生类中仍是虚函数,如果累中至少有一个纯虚函数,那么这个类被称为抽象类。
抽象类不仅包括纯虚函数,也可以包括虚函数,抽象类不能直接创建实例,只能作为基类派生子类,但是仍可以使用指向抽象类的指针支持运行时多态性(虚函数+继承)
7、C++中的重载、重写、重定义
重载:overload,函数签名不一样,是在一个类的内部发生
重写:override,函数签名一样,但必须是父类的虚函数,是在继承关系中出现的,重写函数的访问修饰符可以不同。
重定义:redefining,又叫隐藏,子类重定义了与父类中函数签名相同的非虚函数
8、求下面函数的返回值

//假定x = 9999
int func(x)
{
  int countx = 0;
  while(x)
  {
    countx++;
    x = x & (x - 1);
  }
  return contx;
}

答案:8,思路:将x化为2进制,数1的位数
9、什么是“引用”?申明和使用“引用”要注意哪些问题?
引用就是目标变量的别名,对引用的操作和对目标变量的操作完全相同。申明引用切记要初始化,然后不能再把该引用名称作为其他变量的别名,引用不占存储单元,不能为数组申明引用。一般参数传递时传引用可以减少函数调用时因内存拷贝引起的开销。
10、将引用作为函数参数有哪些特点。
(1)首先,传递引用和传递指针的效果是一样的,但引用更容易使用且程序的可读性更好,另外传递引用在被调函数中不需要给形参分配存储单元,但是传递指针仍需要。
(2)使用引用传递函数参数,在内存中并没有产生实参副本,他是直接对实参操作;而使用一般变量传递参数,当发生函数调用时,需要给新参分配存储单元,新参变量是实参变量的副本,如果传递的是对象,如果传递的是对象,还将调用拷贝构造函数。因此,当传递参数的数据量较大时,用引用比用一般变量传递参数的效率和所占空间都好
(3)传递引用(指针)时,在被调函数中对形参的操作就是对齐相应目标对象的操作。
11、在什么时候需要使用“常引用”?
如果即需要利用引用来提高传参效率和内存占用,又需要避免被调函数对实参的改变,就需要使用常引用。
12、将引用作为函数返回值类型的格式、好处和需要遵循的规则
格式:

type &funcName([arg1, [arg2, arg3, ....]]){
  //函数体
}

好处:在内存中不产生被返回值的副本;(正是由于这个原因,返回一个局部变量的引用时不可取的。因为随着局部变量的生存期结束,相应的引用也会实效,产生runtime error)
注意事项:
(1)不能返回局部变量的引用
(2)不能返回函数内部new分配的内存的引用,这种情况虽然不会产生局部变量被动销毁问题,但是又面临其他的尴尬,例如,如果被返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间就无法释放,造成memory leak。
(3)可返回类成员的引用,但最好是const,
(4)流操作符重载返回值申明为引用的作用:
流操作符<<和>>,这两个操作符经常被连续地使用(cout << "hello" << endl;)因此流操作符的返回值首先得可以作为流操作符的参数,这首先就可以排除掉返回引用的选择,其次,如果返回一个流对象,程序必须重新拷贝一个新的流对象,也就是说,连续的两个流操作符实际上针对的是不同的对象,这也是无法接受的。所以返回引用就成了流操作符的唯一选择,这说明了引用的重要性和无可替代性,也许这就是c++引入引用的原因吧。(赋值操作符“=”和流操作符“<< >>”的情况差不多)
(5)有些操作符却千万不能返回引用:+-*/四则运算符,主要原因是这四个操作符没有side effect,因此,他们必须构造一个对象作为返回值,可选方案有:返回一个对象、返回一个局部变量的引用,返回一个new分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,2、3两个方案都被否决了。静态对象的引用又因为((a+b) == (c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。
13、结构和联合有何区别?
(1)结构和联合都是由多个不同的数据类型成员组成,但在任何时刻,联合中只存放了一个被选中的成员(所有成员公用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)
(2)对于联合的不同成员赋值,将会对其他成员重写,原来的成员值就不存在了,而对于结构的不同成员赋值是互不影响的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值