C++笔试题合集:
1、什么是虚函数?什么是纯虚函数?
1>在类中定义函数时,在函数名前加上virtual关键字,该函数就是虚函数,虚函数可以保证在父子类中只有一个该函数。
2>当虚函数头 = 0;时该函数就是纯虚函数,当类中的某些成员函数没有实现的意义,仅仅时该类中拥有的功能,又想要在子类将其重写后,可以使用父类的指针和引用调用该函数,此时就可以将该函数设置为纯虚函数。
2、基类为什么需要虚析构函数?
1>如果基类的析构函数是虚的,则会先调用派生类的析构函数,再调用基类的析构函数,确保所有的资源都被清理干净,同时防止内存泄漏。
2>如果基类的析构函数是虚的,那么在删除一个指向派生类对象的基类指针时,程序将首先调用派生类的析构函数,然后再调用基类的析构函数,保证了在对象销毁时同样具有多态性。
3、如何初始化const和static数据成员?
1>const数据成员不能在构造函数体内直接赋值(除非构造函数中有默认参数),所以通常在类的外部定义这些成员并进行初始化。可以在类外初始化,也可以通过构造函数初始化列表。
2>static数据成员在类的所有实例之间共享,因此它必须在类外初始化,static
数据成员可以通过类名直接访问,不需要创建类的实例。
4、指针和引用的区别?
在 C++ 中,指针和引用是两种不同的方式来间接访问和操作变量。
1>有空指针,但是没有空引用;
2>引用必须初始化,但是指针可以不初始化;
3>有多级指针,但是没有多级引用;
4>引用的大小与引用的目标本身大小一致,而指针的大小是固定的8字节(64位);
5>引用代表的是被引用目标本身,而指针代表的是指向目标的首地址;
6>引用不占用内存空间使用的是引用目标的空间,而指针占用内存空间。
指针操作起来更为灵活,但是操作方式较为复杂也有潜在的风险(如内存泄漏)。引用简化了语法,并且强制绑定,但不能用于处理空引用的情况。
5、new和malloc的区别?
在 C++ 中,new
和 malloc
都是用来动态分配内存的手段。
1>new申请空间时可以给空间进行初始化,而malloc不可以;
2>new申请对象空间时,会自动调用该对象所在类中的构造函数,而malloc不会;
3>malloc申请的空间是void*类型,使用时需要根据具体的情况进行强转,而new申请空间时返回指针的类型与申请空间的类型有关。
当你需要动态创建对象,并且希望构造函数和析构函数能被系统自动调用时,可以使用new。
当你在 C++ 程序中需要兼容 C 语言并且不需要系统自动调用构造函数和析构函数时,可以使用malloc。
6、内存泄漏是如何产生的?如何避免?
内存泄漏的产生:
1>动态分配的内存没有通过相应的 delete
或 delete[]
操作释放;
2>分配了内存后,没有保存好指向这块内存的指针,导致无法访问或释放这块内存;
3>当使用基类指针管理派生类对象时,如果没有使用虚析构函数,可能会导致派生类的部分内存没有被释放。
如何避免:
1>动态分配的内存使用完毕后要及时使用delete或delete[]释放;
2>可以使用智能指针。
7、C++的内存分区?
1>栈区:由编译器自动分配和释放,存放函数的参数值、局部变量,随着函数的调用而分配,函数结束时自动释放。
2>堆区:由程序员分配和释放,使用 new
和 delete
或者 malloc
和 free
进行操作。
3>静态区:包含全局变量和静态局部变量。
4>常量区:存储字符串等常量且不允许被修改。
5>代码区:存储程序的机器码且不可写入更不可修改。
8、常用的数据结构有哪些?时间复杂度和空间复杂度如何使用?
1>数组、链表、栈、队列、哈希表、树、图。
2>时间复杂度和空间复杂度是用来评估算法效率的重要指标。