C++常考题目参考本
1、指针和引用的区别
实体与别名
内存分配,指针需要引用不需要
sizeof() 对象的大小和本身的大小
引用不能为空
2、堆和栈的区别
堆自己申请自己释放,new/delete
栈自动分配与释放 函数参数、局部变量、临时变量
全局区 全局变量与静态变量放在一起
文字常量区 常量字符串
程序代码区 函数的二进制代码
3、 new和delete是如何实现的,new 与 malloc的异同处
n/d 底层封装的是m/f
m/f标准库函数,n/d是运算符
m/f对非内部类型无用
C只能用 m/f
开辟一个指针 new有类型信息,m则返回的是void指针
4、C/C++区别
过程、对象,结构化语言重点在算法和结构
C++引入了类这一概念
5、 C++、Java的联系与区别,包括语言特性、垃圾回收、应用场景等(java的垃圾回收机制)6、Struct和class的区别
数据结构的实现体/对象的实现体
public/private
7、define 和const的区别(编译阶段、安全性、内存占用等)
简单替换无安全类型检查/有类型检查
有些编译器可对后者进行调试
const节省空间避免不必要的内存分配
8、 在C++中const和static的用法(定义,用途)
const 只读变量、函数参数和返回值、成员函数不可修改成员数据
静态变量
隐藏作用 多文件时只在本文件内可见
具有记忆功能 ,全局生存期
全局变量默认初值为0
对于类中
静态成员属于整个类儿不是对象无this指针
静态成员函数不能定义为虚函数
静态数据成员必须初始化(类外)
9、 const和static在类中使用的注意事项(定义、初始化和使用)
同上
10、 C++中的const类成员函数(用法和意义)
可以与非const函数重载
const与非const同时出现时,非调非,只要const对象非可调用const
const成员变量在初始化列表中进行
const数据成员
引用
类成员为没有默认构造函数的类类型
如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数
初始化类对象.因为如果不是在初始化列表中初始化,该类对象的构造函数会调用两次,这个开销显然有点大
11、 计算下面几个类的大小: class A {};: sizeof(A) = 1; class A { virtual Fun(){} };: sizeof(A) = 4(32位机器)/8(64位机器); class A { static int a; };: sizeof(A) = 1; class A { int a; };: sizeof(A) = 4; class A { static int a; int b; };: sizeof(A) = 4;12、 给一个代码,求输出结果 class A { public: A(int x){} } 问:A a = 1;是否正确, 如果正确, 那么它调用了哪些函数? 这类题目更常见的是在基类和子类有不同实现方法。(虚函数相关,栗子很多,不多说了)13、 C++的STL介绍(这个系列也很重要,建议侯捷老师的这方面的书籍与视频),其中包括内存管理allocator,函数,实现机理,多线程实现等14 、STL源码中的hash表的实现15 、STL中unordered_map和map的区别16、 STL中vector的实现17、 vector使用的注意点及其原因,频繁对vector调用push_back()对性能的影响和原因。18、 C++中的重载和重写的区别:
重载是根据参数表确定调用哪个函数,不关心返回类型,C语言没有重载,C++编译器根据函数不同的参数表对同名函数做修饰,对函数的调用在编译期间就存在了,重载与多态无关
子类重新定义父类虚函数
重写与多态真正相关,当子类重新定义了父类的虚函数后,父类指针根据赋予它的不同的子类指针,动态的调用属于子类的该函数,因此函数地址是在运行期绑定的
19、C ++内存管理(热门问题)链接
五个区 堆 栈 自由存储区、全局/静态 常量存储区
自由存储区是C++基于new操作符的一个抽象概念,由new申请的为常量存储区
20 、介绍面向对象的三大特性,并且举例说明每一个。
封装: 客观事物封装成类,并拥有自己数据和方法让自己可信的类和对象进行操作,对不可信的进行隐藏
继承: 可以使用现有类的所有功能,实现代码的重用
多态:具有不同功能的函数可以用同一函数名,这样就可以用一个函数名调用不同内容的函数
21、 多态的实现(和下个问题一起回答)22、 C++虚函数相关(虚函数表,虚函数指针),虚函数的实现原理(热门,重要)
虚函数表与虚指针
虚函数指针:在含有虚函数类的对象中,指向虚函数表,在运行时确定
虚函数表:在程序中的只读数据段,存放虚函数指针,如果派生类实现了积累的某个虚函数,则在虚表中覆盖原本基类的那个虚函数指针,在编译阶段根据类的声明创建
虚函数表的构造过程
拷贝基类虚函数表
替换已重写虚函数指针
添加自己虚函数指针
23、 实现编译器处理虚函数表应该如何处理24、 析构函数一般写成虚函数的原因
因为在用基类指针指向派生类时,析构函数执行是先调用派生类的析构函数,其次调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销派生类的动态对象,那么在delete时只调用了基类的析构函数
定义了析构函数一定要再定义拷贝构造函数与赋值构造函数
25、 构造函数为什么一般不定义为虚函数
虚函数的作用是实现部分和默认的功能,故父类为虚析构函数则子类会覆盖掉父类的构造函数,失去了一些初始化功能
虚函数调用虚函数表构造对象的时候还没有为虚函数表分配内存,违背了先实例化后调用的准则
对象的创建需要在编译的过程中确定,多态是在运行过程中实现的
26、 构造函数或者析构函数中调用虚函数会怎样
假设我们在基类的构造函数中调用派生类的某个函数去访问其他成员,这会派生类的对象还没构建完成,怎么能访问呢?
于是C++禁止了这种行为
27、 纯虚函数
纯虚函数只是个接口是个函数的声明,要留到子类中去实现
含有纯虚函数的类是基类
我们不能创建抽象基类的对象
28、 静态绑定和动态绑定的介绍 连接
首先明确几个名词定义
静态类型: 对象在声明时采用的类型,在编译期已确定
动态类型: 通常是指一个指针或引用目前所指的对象的类型,在运行期间决定
静态绑定: 绑定的是静态的类型,所对应的的函数依赖于对象的静态类型,发生在编译期
动态绑定: 绑定的是动态类型,所对应的函数或者属性依赖于对象的动态类型
对象的动态类型可以修改,但是静态类型无法修改
在继承体系内只有虚函数使用的是动态绑定,其他全部是静态绑定
29、 引用是否能实现动态绑定,为什么引用可以实现
因为对象的类型是确定的,在编译期就确定了
指针或引用是在运行期根据他们绑定的具体对象确定的
30、深拷贝和浅拷贝的区别(举例说明深拷贝的安全性)
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针
当有动态生成的对象时,默认拷贝函数是浅拷贝,指向同一块内存区域,析构时两次析构,会有内存泄露连接
31 、对象复用的了解,零拷贝的了解
如果应用程序永远不会对这块数据进行修改,那么就永远不需要将数据拷贝到应用程序中的地址中去
(32) 介绍C++所有的构造函数 (33) 什么情况下会调用拷贝构造函数(三种情况) (34) 结构体内存对齐方式和为什么要进行内存对齐? (35) 内存泄露的定义,如何检测与避免? (36) 手写实现智能指针类(34-37我没遇见过) (37) 调试程序的方法 (38) 遇到coredump要怎么调试 (39) 内存检查工具的了解 (40) 模板的用法与适用场景 (41) 成员初始化列表的概念,为什么用成员初始化列表会快一些(性能优势)? (42) 用过C11吗,知道C11新特性吗?(有面试官建议熟悉C11) (43) C++的调用惯例(简单一点C++函数调用的压栈过程) (44) C++的四种强制转换
网友评论