9.26作业(C++面试题)

什么是虚函数?什么是纯虚函数?

虚函数是在基类中用virtual声明的成员函数,应许在派生类中重写该函数,虚函数主要实现多态性。

虚函数的特点是在动态绑定时,虚函数的调用在运行时决定,而不是编译时,通过基类指针或引用调用虚函数时,实际调用的是派生类的重写。
虚函数通常通过基类的指针或引用来调用,实现对不同派生类实例化对象的统一操作。

虚函数可以在基类中实现也可以在派生类中重写。

纯虚函数是在基类中为虚函数但没有实现的函数,使用=0来表示,纯函数使得基类成为抽象类,不能实例化对象。

纯虚函数的特点是属于抽象类,不能创建该类的实例化对象,抽象类的目的是提供一个接口供派生类实现;派生类必须重新所有纯虚函数才能被实例化,如果派生类没有实现所有的纯虚函数,它也会成为抽象类;纯虚函数常用于定义接口,确保派生类提供特定的功能实现。

基类为什么需要虚析构函数?

为了解决在使用delete释放基类指针时,由于基类的指针的作用域仅仅是基类空间的内容,可以完成对基类空间的释放,派生类的空间无法释放,导致内存泄漏的问题,当基类的析构函数设置成虚析构函数时,能够指引delete关键字在释放基类指针时,连同派生类的空间异同释放、

如果初始化const和static数据成员

const数据成员必须在构造函数的初始化列表中进行初始化,因为它们不能再构造函数体内被赋值

static数据成员属于类本身而不是类的某个对象的变量,必须在类外进行初始化,不能在类定义中直接初始化。

指针和引用的区别

有一些几点区别

  1. 在定义时

指针是一个变量,它存储另一个变量的内存地址。指针可以指向任何类型的数据,包括基本数据类型、对象、数组等。

引用:引用是一个别名,它是一个已存在变量的别名。引用必须在声明时初始化,并且一旦绑定到一个变量,就不能再绑定到其他变量。

  1. 初始化

指针:可以在声明时不初始化,之后可以指向任何变量或设置为空

引用:必须在声明时初始化,并且不能在后续代码中更改引用的对象

  1. 重新绑定

指针:可以在任何时候重新指向另一个变量。

引用:一旦绑定到一个变量,就不能再绑定到其他变量。

  1. 内存管理

指针:指针可以动态分配内存,并且需要手动释放内存。

引用:引用不需要手动管理内存,因为它们只是变量的别名,不涉及内存分配

  1. 空值

指针:可以指向空,表示不指向任何有效的内存地址

引用:不能为引用赋值为 空,引用必须始终引用一个有效的对象

总结:指针:可以指向任何类型的变量,支持动态内存管理,可以重新绑定,允许空值,使用时需要解引用。

引用:是变量的别名,必须在声明时初始化,不能重新绑定,不能为空,使用时更为简洁

New和malloc的区别

1: malloc\free是标准库中提供的函数,属于函数调用,而new\delete是C++中的关键字,无需开辟函数内存空间

2:malloc\free申请空间时,没有单个和连续空间的区别,而new\delete申请时区分单个和连续空间的操作

3:malloc\free申请空间时,需要手动计算要申请空间的大小,而new\delete申请空间时,会自动计算大小

4>:malloc\free申请空间时,以字节为单位,而new\delete申请空间时,以数据类型为单位

5:new申请空间时可以给空间进行初始化,而malloc不可以

6: malloc申请出的空间结果是void*类型,使用时需要根据具体的情况进行强转,而new申请空间时,申请什么类型的空间返回的就是什么类型的指针

7:new申请对象空间时,会自动调用该对象所在类中的构造函数,而malloc不会

8:delete释放对象空间时,会自动调用该对象所在类的析构函数,而free不会

9:在new和delete的底层实现中,还是调用了c语言中的malloc、free

内存泄漏怎么产生的?如何避免?

产生原因:

1:在使用 new 或 malloc 动态分配内存后,如果没有使用 delete 或 free 释放内存,就会导致内存泄漏;

2:在重新分配内存时,如果没有释放原有的内存,可能会导致内存泄漏。

3:在异常发生时,如果没有适当的内存释放机制,可能会导致内存泄漏。

4:没有正确管理内部指针,可能会导致内存泄漏

如何避免:

1:使用 new 或 malloc 分配内存后,确保在适当的地方使用 delete 或 free 释放内存。

2:在重新分配内存之前,确保释放原有的内存。

C++的内存分区

主要分区有

栈:栈是用于存储局部变量和函数调用信息的内存区域。

栈的特点:是栈内存由编译器自动分配和释放,函数调用结束后,局部变量的内存会自动释放。栈的分配和释放速度非常快,因为只需移动栈指针。栈的大小通常较小,受操作系统限制,过多的递归调用或大数组可能导致栈溢出

堆:堆是用于动态内存分配的内存区域

堆的特点:堆内存需要程序员手动分配(使用 new 或 malloc)和释放(使用 delete 或 free;

堆的大小仅受系统内存限制,可以动态分配任意大小的内存;由于需要管理内存分配和释放,堆的分配和释放速度相对较慢;如果忘记释放堆内存,可能导致内存泄漏。

C数据段:数据段用于存储全局变量和静态变量。

C数据段特点:储已初始化的全局变量和静态变量;存储未初始化的全局变量和静态变量;

 代码段:代码段存储程序的可执行代码

代码段特点:代码段通常是只读的,以防止程序在运行时修改自身的代码;多个进程可以共享同一段代码,节省内存

总结:

栈:用于存储局部变量和函数调用信息,自动管理,速度快,但大小有限。

堆:用于动态内存分配,灵活性高,但需要手动管理,速度较慢,存在内存泄漏风险。

数据段:存储全局变量和静态变量,分为初始化和未初始化部分。

代码段:存储程序的可执行代码,通常是只读的。

说说你常用的设计模式和应用场景

常用的数据结构有哪些?时间复杂度和空间复杂度如何使用?

数组:时间复杂度:O(1);空间复杂度:O(n),n为数组的大小

链表:时间复杂度:O(n) 空间复杂度:O(n)

栈:时间复杂度:O(1);空间复杂度:O(n)

队列:时间复杂度:O(1);空间复杂度:O(n)

哈希表:时间复杂度:O(1),空间复杂度:O(n)

二叉树::O(log n);空间复杂度:O(n)

图:时间复杂度:

查找边:O(V + E)(V为顶点数,E为边数)

插入边:O(1)(在邻接表中)

删除边:O(E)(在邻接表中)

空间复杂度:O(V + E),V为顶点数,E为边数。

集合:时间复杂度:O(1);空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值