C++笔试面试题

1. 指针和引用区别

指针是一个变量,其值为另一个变量的地址。引用相当于创建一个已存在变量的别名。

指针可以是空指针但是引用必须有初值,指针赋值后可以改变而引用赋值后不能重新赋值

指针使用时需要使用*取地址,而引用可以直接使用。

指针有大小,而引用是在源地址上进行修改,没有大小。

2. 类和结构体区别

类的默认访问控制权是private而结构体的默认访问控制权是public

类的继承默认是private而结构体的默认继承为public

类一般会封装较复杂的功能,会封装数据以及相关的操作接口方法等。结构体一般封装较简单的结构。

3. C++中Static、const作用

static意为静态的,在C语言中可以修饰变量。如果是全局变量则只能在当前文件范围访问。

如果是函数内的局部变量则延长生命周期到整个程序。这意味着如果函数被多次调用,这个变量不会被重新初始化,而是保留上次调用结束时的值。

在C++中,static 还可以用于类成员,表示该成员是类的所有对象共享的,而不是每个对象独立拥有一份。静态成员可以在类外部定义,并且可以通过类名直接访问,而不需要创建类的实例。

const 意为常量,在C语言中修饰的常量在初始化后不能被修改 。在c++中可以将成员函数声明为 const,这表明该函数不会修改对象的状态。const 也可以用于类的对象,创建一个常量对象意味着该对象的所有成员(除非特别标记为 mutable)都不能被修改。

4. C和C++的区别

C 是面向过程的编程,而C++是半面向对象的方法

C++对于C而言更加的灵活, 具有封装继承多态的面向对象特征。

C++以类为基础,通过类将数据和操作数据的函数封装在一起。便于操作者使用

C++可以通过继承机制减少编程的代码量,避免了代码冗余维护也更加简单。

C++通过虚函数实现多态,这使得程序可以根据对象的实际类型来调用相应的函数。

C++具有更严格的数据类型判断机制,具有更完善的异常处理机制,可以使用try catch throw进行异常情况的其他类型输出。

5. 什么是构造函数、析构函数?

构造函数是一种特殊的成员函数,用于在创建对象时初始化对象的数据成员。它的名字与类名相同,没有返回值。

一般有无参构造函数,有参构造函数,拷贝构造函数,移动构造函数等等

析构函数是另一种特殊的成员函数,用于在对象销毁时进行清理工作,如释放对象占用的资源(动态分配的内存、打开的文件、网络连接等)。析构函数的名字是在类名前加上~符号,并且也没有返回类型

析构函数在手动分配内存,手动打开过文件或网络,有使用互斥锁等环境下需要手动定义。

6. New、delete、malloc、free区别

使用new时会调用类的构造函数来构造对象,无需手动的申请空间。malloc需要手动定义开辟空间的大小,

如果new/delete无法完成分配/释放内存的动作则会主报错。malloc则需要手动的检测是否成功申请内存。

7. 虚函数的作用?

虚函数是C++中用于实现多态的一种机制, 虚函数可以在类的派生类中进行重写,每重写一次虚函数都会在虚函数表生成一个新的虚函数指针,提供了一种统一的方式来访问基类及其所有派生类的成员函数。这意味着你可以编写针对基类设计的代码,而同时能够处理多种不同类型的派生类对象。当通过基类指针或引用访问虚函数时,实际调用的是指针或引用所指向的对象的实际类型中定义的那个函数版本。

8. 对多态的理解?多态的原理?

c++中实现多态的关键在于虚函数,在基类的派生类中重写虚函数可以实现多态。多态性是指一个基类的指针或引用可以指向其派生类的对象,并且可以通过这个指针或引用来调用被指向对象的实际类型的成员函数。可以实现用父类的函数指针调用子类函数。

9. 为什么在继承中将析构函数定义为虚析构函数?

通过基类指针删除派生类对象时,如果基类的析构函数不是虚函数,那么只有基类部分会被正确析构,而派生类部分不会被析构。如果基类的析构函数是虚函数,那么即使通过基类指针删除派生类对象,也会调用派生类的析构函数。

10. 构造函数可以定义成虚函数么

构造函数不能被定义为虚函数,构造函数不能多态。

11. vector与list的区别,vector、list、map是什么存储结构

vector 是一个动态数组 ,它在内存中占用连续的空间。当你向 vector 中添加元素时,如果当前预留的空间不足以容纳新的元素,vector 会自动重新分配一块更大的内存,并复制现有的元素到新位置。

list 是一个双向链表 ,每个元素都包含指向其前一个元素和后一个元素的指针。因此,list 不占用连续的内存空间。

map 是一个关联容器,它以键值对的形式 存储数据,并且按键排序。在 C++ 中,map 通常是通过红黑树实现的,这是一种自平衡二叉搜索树。

12. 迭代器的作用

迭代器是一种对象,它充当指向容器中元素的指针。

C++标准库中的迭代器分为五种类型,每种类型提供了不同程度的操作能力:

  1. 输入迭代器(Input Iterator):只读迭代器,可以读取元素,但不能修改。
  2. 输出迭代器(Output Iterator):只写迭代器,可以写入元素,但不能读取。
  3. 前向迭代器(Forward Iterator):可以读写元素,支持单向遍历。
  4. 双向迭代器(Bidirectional Iterator):除了前向迭代器的功能外,还支持反向遍历。
  5. 随机访问迭代器(Random Access Iterator):提供了所有前面迭代器的功能,并且支持随机访问(例如通过索引直接访问元素)。

13. 智能指针有哪些?

分为独占智能指针,共享智能指针,弱智能指针。

独占智能指针独占资源的所有权,可以使用move将其所有权转移给另一个独占智能指针,当智能指针被销毁时,它会自动销毁所指向的对象。

共享智能指针允许多个指针共享同一块内存。每个shared_ptr都有一个引用计数,当最后一个共享智能指针被销毁或重置时,它所指向的对象才会被销毁。

弱智能指针是对共享智能指针所管理对象的非拥有(non-owning)引用。它不会影响共享智能指针的引用计数。用于解决循环引用问题。

14. C++11新特性有哪些?

c++11 有自动变量类型**auto 和** 表达式的类型**decltype**

加入了Lambda 表达式允许在代码中直接定义匿名函数,简化了函数对象的创建

引入了智能指针,细节如上。

静态断言允许在编译期进行条件检查,如果条件不满足则编译失败。

变长参数模板,允许函数模板接收可变数量的参数。

引入原子操作,支持无锁编程。

可以使用using替代了typedef

等等

15. 深拷贝和浅拷贝区别

深拷贝不仅复制对象本身,还复制对象内部的所有引用类型字段指向的对象。这意味着原始对象和副本对象中的引用类型字段将指向不同的内存区域。深拷贝完全隔离对象及其内部数据,避免了指针的二次释放等问题。

16. This指针的作用

this指针可以访问当前对象的成员,在类内时可以区分局部变量和成员变量。可以传递当前对象给其他函数等等。

  1. 重载、覆盖、隐藏的区别?

重载是在同一个作用域内(通常是同一个类中)定义多个具有相同名称但参数列表不同的函数。编译器根据调用时传递的参数类型和数量来决定调用哪个函数。

覆盖(重写)是指派生类中定义一个与基类中虚函数具有相同签名(函数名、参数列表和返回类型)的函数。覆盖允许派生类提供自己的实现,以改变或扩展基类的行为。

隐藏是指派生类中定义了一个与基类中函数具有相同名称但参数列表不同的函数。即使基类中的函数是虚函数,派生类中的函数也不会覆盖它,而是隐藏它。

  1. 访问权限private、protected、public区别?
特性/访问权限 private protected public
类内部 可以访问 可以访问 可以访问
派生类 可以访问 可以访问
类外部 可以访问
友元类/函数 可以访问(如果被声明为友元) 可以访问(如果被声明为友元) 可以访问(如果被声明为友元)
说明 只能在类的内部访问,保护数据不被外部直接访问。 可以在类的内部和派生类中访问,提供了某种程度的封装,同时允许派生类访问。 可以在类的内部、派生类和类的外部访问,最不严格的访问权限。
  1. 什么是抽象类?

抽象类中至少有一个纯虚函数,导致它不能被实例化,只能作为基类被其他类继承。抽象类的主要目的是为派生类提供一个共同的接口。

相关推荐
军训猫猫头14 分钟前
36.矩阵格式的等差数列 C语言
开发语言·c++
数学人学c语言16 分钟前
从熟练Python到入门学习C++(record 1)
c++·学习
凤枭香1 小时前
数字图像处理(c++ opencv):图像分割-基本边缘检测
c++·图像处理·opencv·计算机视觉
希言JY1 小时前
C语言 | 指针 | 野指针 | 数组指针 | 指针数组 | 二级指针 | 函数指针 | 指针函数
c语言·开发语言
别开生面的阿杰1 小时前
蓝桥杯-洛谷刷题-day4(C++)
c++·职场和发展·蓝桥杯
尘海折柳1 小时前
C++ STL知识点100问
c++·面试·stl
CodeWithMe1 小时前
【C/C++】Lambda 用法
c语言·c++
悄悄敲敲敲2 小时前
C++:异常
开发语言·c++
Xing-Zhuang2 小时前
C++笔记
开发语言·c++·笔记
CyberMuse2 小时前
北京大学c++程序设计听课笔记101
c++