9.26作业
C++ 面试题
1,什么是虚函数?什么是纯虚函数?
虚函数:父子类中,在父类中的函数需要在子类中进行重写,重写后父子类空间中使用的都是重写后的函数,该函数就是虚函数,虚函数的声明需要在函数前加virtual。
纯虚函数:父子类中,在父类中声明为虚函数但是没有实现的函数,通过在函数声明后加上 = 0 来表示是纯虚函数,包含纯虚函数的类是抽象类,无法实例化对象,且纯虚函数需要子类进行重写,如果子类没有重写,那么子类也是抽象类。
2.基类为什么需要虚析构函数?
解决多态遗留下的问题:当父类指针指向子类对象在堆区申请的空间时,申请空间会先构造父类,再构造子类,但是在使用delete释放父类指针时,由于父类指针的作用域仅仅只是父类空间的内容,可以完成对父类空间的释放,但是,子类自己的空间无法释放,导致内存泄漏。
解决方法:在父类中设置虚析构函数,确保在通过父类指针删除子类对象时,能够正确调用子类的析构函数,避免内存泄露。
3.如何初始化 const和 static 数据成员?
const数据成员必须在类的构造函数的初始化列表中完成初始化工作,不能在类定义中直接初始化。
static数据成员是静态成员变量,不依附于类对象而存在,在类中声明,必须在类外部定义并初始化。
4.指针和引用的区别
指针是记录指向目标的起始地址;指针需要8字节的存储空间;指针可以有空指针;指针指向目标后可以修改指向目标;定义指针时可以不初始化;指针还可以定义指针数组;指针的偏移,就是偏移目标单位内存空间的大小。
引用是引用目标的别名,本质就是引用目标;引用和引用目标是同一个存储空间;引用没有空引用;引用指定目标后,不可以进行修改;引用必须要初始化;引用中没有引用数组;引用在进行偏移时,就是对目标进行的偏移。
5.new 和 malloc的区别
1、malloc是C语言中标准库中提供的函数,new是C++中的关键字,无需开辟函数内存空间;
2、malloc没有单个和连续申请的区别,new申请空间时区分单个和连续空间的操作;
3、malloc申请空间时需要手动计算要申请空间的大小,new申请空间时,会自动计算大小;
4、malloc申请空间时以字节为单位,new申请空间时以数据类型为单位;
5、malloc申请空间时无法进行初始化,new可以进行初始化工作;
6、malloc申请空间后返回的是void*类型,使用时需要根据具体的情况进行强转,new申请空间时,申请什么类型的空间返回的就是什么类型的指针;
7、new申请对象空间时,会自动调用该对象所在类中的构造函数,而malloc不会。
6.内存泄漏怎么产生的?如何避免?
内存泄漏的产生原因:
1、未释放动态分配的内存:使用 new 或 malloc 分配内存后,未调用 delete 或 free 释放内存。
2、异常处理:在分配内存后发生异常,导致后续的释放代码未被执行。
3、指针丢失:将指针重新赋值或超出作用域,导致原有指针指向的内存无法访问。
4、循环引用:在使用智能指针时,两个或多个对象相互引用,导致内存无法释放。
避免内存泄漏的方法
1、确保释放内存:在使用 new 或 malloc 分配内存后,确保在适当的位置调用 delete 或 free。
2、异常安全:使用 RAII(资源获取即初始化)原则,确保在构造时分配资源,在析构时释放资源。
3、避免指针丢失:在重新赋值指针之前,确保释放原有的内存,或者使用智能指针来管理内存。
4、使用智能指针:C++11 引入了智能指针(如 std::unique_ptr 和 std::shared_ptr),它们会自动管理内存,避免手动释放内存的错误。
7.C++的内存分区
1、代码段:存储程序的可执行代码,通常是只读的,以防止程序在运行时意外修改其指令。
2、数据段:
.bss 区用于存储未初始化的全局变量和静态变量;
.data 区用于存储已初始化的全局变量和静态变量;
.ro区用于存储const修饰的变量常量;
.text 区用于存储文本和代码段。
3、堆区:用于动态内存分配。通过 new 和 malloc 等函数分配的内存都来自堆。
4、栈区:用于存储局部变量、函数运行空间和返回地址。栈的大小通常是固定的,超出栈的大小会导致栈溢出。
8.常用的数据结构有哪些?时间复杂度和空间复杂度如何使用
数组:固定大小的线性数据结构,存储相同类型的元素。时间复杂度:访问:O(1),插入/删除(在中间):O(n),空间复杂度:O(n)。
链表:由节点组成的线性数据结构,每个节点包含数据和指向下一个节点的指针。时间复杂度:访问:O(n),插入/删除(在头部或尾部):O(1),空间复杂度:O(n)。
栈:后进先出(LIFO)的数据结构,支持在一端插入和删除元素。时间复杂度:Push\Pop(插入\删除):O(1),空间复杂度:O(n)。
队列:先进先出(FIFO)的数据结构,支持在一端插入元素,在另一端删除元素。时间复杂度:插入\删除:O(1),空间复杂度:O(n)。
哈希表:通过哈希函数将键映射到值的集合,支持快速查找。时间复杂度:查找\插入\删除:O(1)(平均情况),空间复杂度:O(n)。
二叉树:每个节点最多有两个子节点的树形结构。时间复杂度:查找\插入\删除:O(n)(最坏情况),空间复杂度:O(n)。
时间复杂度:用于评估算法在输入规模增加时所需的时间。通常使用大 O 符号表示。
空间复杂度:用于评估算法在执行过程中所需的额外空间。也使用大 O 符号表示。