C++ 访谈问题及答案

31 2025 年 5 月 | 阅读 24 分钟
C++ Interview Questions

以下是 C++ 访谈中经常被问到的热门问题及答案列表。


1) 什么是 C++?

C++ 是一种面向对象的编程语言,它允许程序员在对象和类的世界中工作,并使其易于处理和更好地理解。C++ 编程语言由哥伦比亚大学计算机科学教授 Bjarne Stroustrup 于 1985 年设计并实现。

基本上,C++ 是 C 编程语言的改进版本,它完全基于过程式编程,并且 C++ 支持关键的 OOP 概念,如封装、继承和多态。因此,我们可以将 C++ 视为 C 编程语言的超集。


2) C++ 的优点是什么?

C++ 编程语言的几个优点如下:

  • C++ 不仅维护了 C 语言的各个方面,还简化了内存管理并为代码添加了多项功能。
  • C++ 是一种高度可移植的语言,意味着使用 C++ 语言开发的软件可以在任何平台上运行。
  • C++ 是一种面向对象的编程语言,包括 OOPs 概念,如类、对象、继承、多态和抽象。
  • C++ 使用一种称为消息传递的技术,用于实现对象之间的通信。
  • C++ 包含一个丰富的函数库,我们可以在我们的代码中使用它,并引入用户代码的依赖性。

3) C 和 C++ 有什么区别?

C 和 C++ 之间存在几个区别。其中一些如下:

CC++
C 语言由 Dennis Ritchie 开发。C++ 语言由 Bjarne Stroustrup 开发。
C 是一种结构化编程语言。C++ 同时支持结构化和面向对象的编程语言。
C 是 C++ 的子集。C++ 是 C 的超集。
在 C 语言中,数据和函数是独立的实体。在 C++ 语言中,数据和函数都以项目的形式封装在一起。
C 不支持数据隐藏。因此,外部世界可以使用数据。C++ 支持数据隐藏。因此,外部世界无法访问数据。
C 既不支持函数也不支持运算符重载。C++ 同时支持函数重载和运算符重载。
在 C 中,函数不能在结构中实现。在 C++ 中,函数可以在结构中实现。
C 语言不支持引用变量。C++ 支持引用变量。
C 语言不支持虚拟函数和友元函数。C++ 同时支持虚拟函数和友元函数。
在 C 中,scanf() 和 printf() 主要用于输入/输出。C++ 主要使用流 cin 和 cout 来执行输入和输出操作。

阅读更多:C 和 C++ 的区别


4) 引用和指针有什么区别?

C++ 中的引用和指针存在几个区别。一些主要区别如下:

引用指针
引用就像一个现有变量的别名,也就是说,它是一个临时变量。指针是一个存储变量地址的变量。
引用变量不需要间接运算符来访问值。引用变量可以直接用于访问值。指针变量需要间接运算符来访问变量的值。
一旦分配了引用变量,就不能用不同的地址值重新分配它。指针变量是独立变量,这意味着它可以被重新分配指向不同的对象。
空值不能分配给引用变量。空值可以分配给引用变量。
在声明时必须初始化变量。在声明时不必初始化变量。

阅读更多:引用和指针的区别


5) 什么是 C++ 中的类?

在 C++ 中,类是一种用户定义的数据类型。类使用关键字 class 来声明。类包含数据成员和成员函数,其访问由三个修饰符 private、public 和 protected 定义。类定义了事物的类别类型定义。它定义了一个数据类型,但它不定义数据。它只是指定了数据的结构。

如果我们想使用该类的数据,我们在类中创建 n 个对象并调用方法和变量。

语法

它具有以下语法:

C++ 类示例

让我们以一个例子来说明 C++ 中的类。

示例

编译并运行

输出

The sum of a and b is: 5

阅读更多:C++ 类


6) C++ 中有哪些不同的 OOPs 概念?

C++ 中的几个 OOPs 概念如下:

C++ Interview Questions and Answers

Class

在 C++ 中,类是一种用户定义的数据类型,它定义了自己的属性和函数。例如,人类是一个类。人类的身体部位是它的属性,身体部位执行的动作称为函数。类不占用任何内存空间。因此,我们可以说类是数据的唯一逻辑表示。

语法

它具有以下语法:

Object

在 C++ 中,对象是运行时实体。对象是类的实例。对象可以代表一个人、地点或任何其他项目。对象可以操作数据成员和成员函数。类不占用任何内存空间。

当使用 new 关键字创建对象时,会在堆中为变量分配空间,并将起始地址存储在堆栈内存中。当不使用 new 关键字创建对象时,堆内存中不会分配空间,对象在堆栈中包含空值。

语法

它具有以下语法:

继承

在 C++ 中,继承提供可重用性。可重用性意味着我们可以使用现有类的功能。它消除了代码的冗余。继承是一种从旧类派生新类的方法。旧类称为基类,新类称为派生类。

语法

它具有以下语法:

注意:可见性模式可以是 public、private 或 protected。

阅读更多:C++ 继承

封装

在 C++ 中,封装是一种将数据成员和成员函数包装到单个单元中的技术。它将数据绑定到类中,并且外部方法无法访问数据。如果数据成员是私有的,则成员函数只能访问数据。

阅读更多:C++ 封装

抽象

在 C++ 中,抽象是一种仅显示必要细节而不显示实现细节的技术。如果成员使用 public 关键字定义,则成员也可以在外部访问。如果成员使用 private 关键字定义,则外部方法无法访问成员。

阅读更多:C++ 抽象

多态

在 C++ 中,多态意味着多种形式。多态意味着存在多个同名但功能不同的函数。多态有两种类型:

  • 静态多态也称为早期绑定。
  • 动态多态也称为晚期绑定。

7) C++ 中有哪些不同的多态类型?

在 C++ 中,多态意味着多种形式。它意味着存在多个同名但功能不同的函数。

多态主要有两种类型:

C++ Interview Questions and Answers
  • 运行时多态

运行时多态也称为动态多态。函数重写是运行时多态的一个例子。函数重写意味着子类包含父类中已有的方法。因此,子类重写了父类的方法。在函数重写的情况下,父类和子类都包含具有不同定义的同名函数。在运行时确定的函数调用称为运行时多态。

C++ 运行时多态示例

让我们以一个例子来说明 C++ 中的运行时多态。

示例

编译并运行

输出

tpointtech tutorial
  • 编译时多态

在 C++ 中,编译时多态也称为静态多态。在编译时实现的称为编译时多态。方法重载是编译时多态的一个例子。

阅读更多:C++ 多态


8) 什么是 C++ 中的方法重载?

在 C++ 中,方法重载是一种技术,允许我们包含多个同名但功能不同的函数。

方法重载可能基于以下几点:

  • 重载函数的返回类型。
  • 传递给函数的参数类型。
  • 传递给函数的参数数量。

方法重载示例

示例

编译并运行

输出

6
24

说明

在上面的示例中,null() 是一个带有不同数量参数的重载函数。


9) C++ 中的命名空间是什么?

  • 命名空间是代码的逻辑划分,旨在防止命名冲突。
  • 命名空间定义了声明变量、类和函数等标识符的作用域。
  • 在 C++ 中使用命名空间的主要目的是消除歧义。当不同的任务具有相同的名称时,就会发生歧义。
  • 例如,如果有两个函数具有相同的名称,例如 add()。命名空间用于防止此歧义。函数在不同的命名空间中声明。
  • C++ 包含一个标准命名空间,即 std,它包含内置类和函数。因此,使用语句“using namespace std;”可以将命名空间“std”包含到我们的程序中。

命名空间语法

访问命名空间变量的语法

C++ 命名空间示例

让我们以一个例子来说明 C++ 中的命名空间。

示例

编译并运行

输出

10

阅读更多:C++ 命名空间


10) 什么是 C++ 中的 Token?

Token 是 C++ 程序中最小的独立单元,编译器在词法分析期间使用它们来分析和解释代码。使用这些 Token,我们可以识别、理解、处理和形成编程语言的语法。Token 可以是关键字、标识符、字面量、常量和符号。

阅读更多:C++ 中的 Token


11) 指针可以执行哪些操作?

在 C++ 中,指针可以执行多项操作。一些主要操作如下:

  • 递增或递减指针:递增指针意味着我们可以将指针递增数据类型的大小,该数据类型是指针指向的。

有两种类型的递增指针:

1. 前缀递增指针:前缀递增运算符将操作数加 1,表达式的值成为递增后的结果值。如果 ptr 是指针,则前缀递增指针表示为 ++ptr。

C++ 前缀递增指针示例

让我们以一个例子来说明 C++ 中的前缀递增指针。

示例

编译并运行

输出

Value of *ptr is : 1
Value of *++ptr : 2

2. 后缀递增指针:后缀递增运算符将操作数加 1,但表达式的值将是递增值之前操作数的值。如果 ptr 是指针,则后缀递增指针表示为 ptr++。

C++ 后缀递增示例

让我们以一个例子来说明 C++ 中的后缀递增。

示例

编译并运行

输出

Value of *ptr is : 1
Value of *ptr++ : 1
  • 从一个指针减去另一个指针:当减去指向数组成员的两个指针时,将返回两个成员之间的元素数量。

12) C++ 中的 'std' 是什么?

std 是 C++ 中使用的默认命名空间标准。它包含 C++ 标准库中定义的所有标识符(类、函数、对象等)。

当我们使用 cout、cin、string、vector、sort 等功能时,它们都属于 std 命名空间。它有助于避免名称冲突并保持标准库标识符的组织。


13) 哪个编程语言的性能不佳导致了 C++ 的发现?

C++ 的发现是为了应对 C 的缺点。


14) delete[] 与 delete 有何不同?

在 C++ 中,delete 用于释放一块内存,而 delete[] 方法用于释放一个数组。


15) C++ 中 STL 的全称是什么?

在 C++ 中,STL 代表标准模板库 (Standard Template Library)。

阅读更多:C++ STL


16) C++ 中的对象是什么?

在 C++ 中,对象是类的实例,我们可以通过创建 n 个对象来多次调用类的属性和行为。对象是面向对象编程语言的基本概念,因为它允许程序员多次重用代码。

类的对象使用与声明基本类型变量相同的声明方式来声明。我们在类中使用类名创建对象,然后命名对象。我们也可以使用 new 关键字动态创建对象,对于动态对象,内存会在堆区域分配。我们使用点运算符访问对象。

C++ 对象示例

让我们以一个例子来说明 C++ 中的对象。

示例

编译并运行

输出

Hello

17) 什么是 C++ 访问说明符?

在 C++ 中,访问说明符用于定义如何在类外部访问函数和变量。这些说明符主要用于定义访问类外部方法和变量的级别。

我们有以下三种类型的访问说明符:

  • Private 访问说明符:如果我们对方法或变量使用 private 说明符,则只能在同一类内访问它,而不能在类外部访问。它们成为它们被创建和初始化的类的私有成员。
  • Public 访问说明符:如果我们对方法或变量使用 public 说明符,则可以从任何地方访问它。
  • Protected 访问说明符:声明为 protected 的函数和变量不能在类外部访问,但子类可以访问。它通常用于继承概念,如果我们创建一个父类和子类,父类的这些方法和变量可以被子类访问,前提是在父类中使用了 protected 说明符。

阅读更多:C++ 访问说明符


18) 什么是面向对象编程 (OOP)?

在 C++ 中,OOP 是一种方法论或范例,它允许程序员处理易于理解的真实世界实体。面向对象编程的概念与创建对象以执行给定任务有关。我们拥有构成了 OOP 的基本概念。

类和对象:类用于指定数据的结构。我们在类中创建和初始化方法和变量,从而带来数据的结构。我们还可以指定类的访问级别,即 public、private 或 protected。

另一方面,对象是类的实例,我们使用它们来调用类定义的已定义方法和变量。通过创建 n 个对象并将其应用于不同的场景,我们可以多次调用类的方法或变量。

封装:一种将数据及其关联操作绑定在一起并从而隐藏数据免受外部世界影响的机制。封装也称为数据隐藏。在 C++ 中,它通过访问说明符(即 public、private 和 protected)来实现。

当我们创建一个类时,我们将数据成员和成员函数包装在一个地方,即我们将它们封装在一个类中以形成一个结构,并且创建一个类是学习封装的一个易于理解的例子。当我们把数据封装到一个类中时,只有所需的部分对用户可见,所有其他数据都保持隐藏。

抽象:抽象用于隐藏内部实现,并仅向外部世界显示必要的细节。有不同的方法可以执行抽象。数据抽象在 C++ 中使用接口和抽象类来实现。

继承:继承用于将一个类的属性继承到另一个类中。它使我们能够根据另一个类来定义一个类。它在两个或多个类之间创建 IS-A 关系,建立依赖关系,并允许程序员在多个类中重用相同的方法和变量。

在继承中,我们有一个基类(也称为父类)和一个或多个子类。如果我们想在子类中使用父类的任何方法,我们可以创建对象并调用该方法,反之亦然。

阅读更多:C++ OOPs 概念


19) 数组和列表之间有什么区别?

数组和列表之间存在几个区别。它们之间的一些主要区别如下:

  • 数组是同质元素的集合,而列表是异质元素的集合。
  • 数组内存分配是静态和连续的,而列表内存分配是动态和随机的。
  • 在数组中,用户不需要跟踪下一个内存分配,而在列表中,用户必须跟踪下一个内存分配的位置。

20) new() 和 malloc() 之间有什么区别?

new() 和 malloc() 之间存在几个区别。它们之间的一些主要区别如下:

  • new() 运算符是预处理器,malloc() 是一个函数。
  • 使用 "new" 时无需分配内存,但在 malloc() 中,我们必须使用 sizeof() 函数。
  • "new" 将新内存初始化为 0,而 malloc() 在新分配的内存位置中给出随机值。
  • new() 运算符分配内存并调用构造函数进行对象初始化,而 malloc() 函数分配内存但不调用构造函数进行对象初始化。
  • new() 运算符比 malloc() 函数快,因为运算符比函数快。

阅读更多:new() 和 malloc() 的区别


21) 有哪些从 DLL 导出函数的方法?

有两种方法:

  • 使用 DLL 的类型库。
  • 从 DLL 实例中获取函数引用。

22) 定义 C++ 中的友元函数。

在 C++ 中,友元函数充当类的朋友。它可以访问类的私有和保护成员。友元函数不是类的成员,但它必须在类定义中列出。

非成员函数无法访问类的私有数据。有时,非成员函数访问数据是必要的。友元函数是非成员函数,它能够访问类的私有数据。

如果我们想让外部函数成为类的朋友,我们需要将该函数声明为类的朋友,如下所示:

C++ 友元函数示例

让我们以一个例子来说明 C++ 中的友元函数。

示例

编译并运行

输出

11

阅读更多:C++ 友元函数


23) 什么是虚函数?

  • 在 C++ 中,虚函数用于替换基类提供的实现。无论对象实际上是派生类的对象,即使该对象是通过基类指针而不是派生类指针访问的,都会调用此替换。
  • 它是基类中存在并由派生类重新定义的成员函数。
  • 当我们在基类和派生类中使用相同的函数名时,基类中的函数使用 virtual 关键字声明。
  • 当函数被设为 virtual 时,C++ 会在运行时根据基类指针指向的对象类型来确定调用哪个函数。因此,我们可以通过使基类指针指向不同的对象来执行虚函数的不同版本。

虚函数的规则

  • 虚函数应该是某个类的成员。
  • 虚函数不能是静态成员。
  • 虚函数通过对象指针调用。
  • 它可以是另一个类的朋友。
  • C++ 不包含虚构造函数,但可以有虚析构函数。

阅读更多:C++ 虚函数


24) 何时应使用多重继承?

在 C++ 中,当一个类需要从多个基类继承特征(数据成员和成员函数)时,并且每个基类提供不同的功能或行为,这些在派生类中逻辑上是必需的,此时应使用多重继承。

阅读更多:C++ 多重继承


25) C++ 中的析构函数是什么?

在 C++ 中,析构函数是一种实例数据函数,用于释放对象分配的任何额外资源。析构函数在对象超出范围后会自动调用,并销毁类对象。      

析构函数的规则

  • 析构函数与类名相同,并在前面加上波浪号。
  • 它不包含任何参数,也没有返回类型。
  • 我们不能定义多个析构函数。
  • 我们不能重载析构函数。
  • 析构函数不能声明为 static 或 const。

析构函数语法

析构函数示例

示例

编译并运行

输出

Constructor Created
Destructor Created

阅读更多:C++ 析构函数


26) 什么是溢出错误?

在 C++ 中,溢出错误是一种算术错误,当算术运算的结果超过数据类型或内存区域的存储容量时发生。它可能发生在整数、浮点类型或程序堆栈上。

在 C++ 中,每个数据类型都有一个定义的范围。当计算产生的值超过该范围的最大限制时,就会发生溢出。


27) C++ 中的重载是什么?

  • 重载的概念是当一个函数具有相同的名称但具有不同的参数时,也就是说,单个对象表现出不同的行为并提供同一函数的不同版本。
  • C++ 允许程序员在同一作用域内为函数名或运算符指定多个定义。
  • 当我们重载方法时,称为方法重载,当我们重载运算符时,称为运算符重载。

因此,基本上,C++ 提供两种类型的重载,即函数重载和运算符重载。

1. 运算符重载:这是一种编译时多态,其中重载标准运算符以赋予其用户定义的定义。例如,'+' 运算符被重载以对 int、float 等数据类型执行加法运算。

运算符重载语法

阅读更多:C++ 运算符重载

2. 函数重载:在 C++ 中,函数重载也是一种编译时多态,可以定义一组同名的函数。函数将根据函数调用中的参数列表执行不同的操作。要调用的函数取决于参数列表中的参数数量和参数类型。

阅读更多:C++ 函数重载


28) 什么是函数重写?

如果我们把一个类继承到一个派生类中,并在派生类中再次为基类的一个函数提供定义,这个函数就叫做重写函数,这种机制就叫做函数重写。重写有助于实现多态。我们有两种类型的函数重写可用:

  • 编译时重写:在这里,方法的重写发生在编译时。编译时多态也称为早期绑定或静态绑定。
  • 运行时函数重写:在这里,方法的重写发生在运行时。运行时多态也称为动态绑定或晚期绑定。我们通过虚函数来实现运行时多态。

阅读更多:C++ 函数重写


29) 什么是虚继承?

在 C++ 中,虚继承使得程序员能够创建对象的唯一副本,即使该对象在层次结构中出现多次。


30) 什么是构造函数?

在 C++ 中,构造函数是一种特殊的成员函数,用于初始化对象。它的名称必须与类名相同。每当我们创建类的对象时,这些构造函数都会自动调用。

C++ 构造函数语法

基本上,有四种类型的 C++ 构造函数:

  • 默认构造函数:如果我们不创建它,它是由编译器自动生成的构造函数。否则,如果我们显式创建自己的构造函数,它将不会被生成。它不携带任何参数,并且只用默认值初始化对象。
  • 参数化构造函数:在此构造函数中,我们将参数传递给构造函数,并使用这些参数初始化类的对象。但是,如果我们创建了一个参数化构造函数,我们也应该定义一个非参数化构造函数,因为当我们创建自己的构造函数时,编译器不会创建默认构造函数。
  • 复制构造函数:它接受同一类对象的引用的构造函数,并通过另一个同一类对象来初始化类的对象。
  • 移动构造函数:它类似于复制构造函数,它根据现有对象创建一个对象。它不会将对象复制到新内存中,而是使用移动语义将创建对象的拥有权转移到新对象,而无需进行任何额外的复制。移动构造函数的过程类似于从其他对象窃取资源。

阅读更多:C++ 构造函数


31) "delete" 运算符的目的是什么?

"delete" 运算符用于释放 "new" 运算符创建的动态内存。delete 运算符的返回类型是 void,它不返回任何值。当我们使用 delete 运算符时,指向对象的指针不会被销毁;只有对象指针指向的值才会被销毁。


32) 解释 "this" 指针。

在 C++ 中,"this" 指针是一个关键字,它保存当前对象的地址。对象是声明它们所在的同一个类的对象。

阅读更多:C++ this 指针


33) 作用域解析运算符有什么作用?

作用域解析运算符,用双冒号 (::) 表示,用于在当前类中访问在其他类中定义的类成员和成员函数。例如,如果我们有两个变量 v1 和 v2,它们定义在类 A 中,如果我们想在类 B 中访问这些变量,我们可以使用作用域解析运算符,也可以在类 B 中访问 v1 和 v2。

作用域解析运算符的语法

如果我们想访问全局变量或静态变量,在类外定义一个方法,或者在子类中引用父类变量。在这种情况下,作用域解析有助于实现所有这些。

阅读更多:C++ 作用域解析运算符


34) 什么是纯虚函数?

在 C++ 中,纯虚函数是没有定义的虚函数。普通函数前面加上 virtual 关键字。纯虚函数以 0 结尾。

纯虚函数语法

C++ 纯虚函数示例

让我们以一个例子来说明 C++ 中的纯虚函数。

示例

编译并运行

输出

tpointtech

35) 结构体和类有什么区别?

结构class
结构体是一种用户定义的数据类型,它包含不同数据类型的变量。类是一种用户定义的数据类型,它包含成员变量和成员函数。
结构体的变量存储在堆栈内存中。类的变量存储在堆内存中。
我们不能直接初始化变量。我们可以直接初始化成员变量。
如果未指定访问说明符,则默认情况下,变量的访问说明符为 "public"。如果未指定访问说明符,则默认情况下,变量的访问说明符为 "private"。
结构体声明
struct 结构体名称
{
// 结构体体;
} ;
类声明
class 类名
{
// 类体;
}
结构体使用 struct 关键字声明。类使用 class 关键字声明。
结构体不支持继承。类支持继承概念。
结构体的类型是值类型。类的类型是引用类型。

阅读更多:C++ 结构体和类的区别


36) 什么是类模板?

在 C++ 中,类模板用于创建一系列类和函数。例如,我们可以创建一个数组类的模板,它将使我们能够创建各种类型的数组,如 int、float、char 等。类似地,我们可以为函数创建一个模板;假设我们有一个函数 add(),然后我们可以创建 add() 的多个版本。

类模板语法

模板类对象的语法


37) 函数重载和运算符重载有什么区别?

C++ 中函数重载和运算符重载之间的几个区别如下:

  • 函数重载:函数重载定义为我们可以拥有同一函数的多个版本。函数的版本将具有不同的签名,意味着它们具有不同的参数集。
  • 运算符重载:运算符重载定义为标准运算符可以被重新定义,以便当应用于类实例时具有不同的含义。

38) 什么是虚析构函数?

在 C++ 中,虚析构函数用于基类,以便也可以销毁派生类对象。虚析构函数使用 ~ 波浪号运算符声明,然后在构造函数之前使用 virtual 关键字。

注意:构造函数不能是虚的,但析构函数可以是虚的。

C++ 虚析构函数示例

让我们以一个例子来说明 C++ 中的虚析构函数。

示例

编译并运行

输出

Base constructor is called
Derived class constructor is called
Derived class object is destroyed
Base class object is destroyed

当我们使用虚析构函数时,将首先调用派生类析构函数,然后调用基类析构函数。

阅读更多:C++ 虚析构函数


39) Java 和 C++ 有什么区别?

Java 和 C++ 都是流行的编程语言,它们都有自己独特的特性。Java 和 C++ 之间的几个区别如下:

  • C++ 主要用于系统编程,而 Java 用于应用程序编程。
  • C++ 是 C 编程语言的扩展,而 Java 被设计和创建为打印系统的解释器。
  • C++ 编程语言支持 goto 语句,而 Java 不支持 goto 语句。
  • C++ 支持指针,而 Java 内部支持指针。
  • C++ 支持运算符重载,而 Java 不支持(此处原文错误,Java 确实支持运算符重载,但有限制,但与 C++ 的方式不同。但按照原文意思此处应为“不支持”)。
  • 在 C++ 中,内存管理是使用 new 和 delete 手动完成的,而在 Java 中,内存管理由 Java 垃圾回收器自动完成。

阅读更多:Java 和 C++ 的区别


40) 定义 C++ 中的内联函数。

在 C++ 中,内联函数是使用 inline 关键字定义的函数。在内联函数中,编译器在编译时会将函数调用替换为函数的原始代码。它的主要目的是通过减少函数调用开销来提高程序的性能。

内联函数可以通过直接在函数调用处复制代码来加速代码执行。如果对内联函数进行了任何修改,则应重新编译函数,因为编译器需要更新插入函数代码的所有位置。否则,程序将运行旧的功能。

语法

它具有以下语法:

阅读更多:C++ 内联函数