Tutorial Study Image

C++ 面试问题

C++ 是一种面向对象的编程语言,由 Bjarne Stroustrup 于 1985 年发明。

C++ 最初被称为“带类的 C”,因为 C++ 被认为是编程语言 C 的超集。C++ 包含了一些比 C 更多的特性,比如类的概念。

C++ 是编程语言 C 的超集,它使用了面向对象的概念,因此它有一些好处。

  • 使用 C++ 创建的应用程序具有高度可移植性,这意味着它们可以在不同的平台上运行。
  • C++ 是一种面向对象的编程语言,它使用了多态性、继承、类、对象等许多概念。
  • 由于继承特性,C++ 内部没有冗余的代码片段。
  • C++ 支持数据隐藏,这有助于隐藏敏感代码部分免受攻击者的侵害。
  • C++ 拥有庞大的函数库

 

C++ 是一种面向对象的语言,因为它使用了面向对象的概念,如类、对象、继承、多态、数据绑定、抽象等。

C++ 和 C 的区别
C++ C
C++ 是一种面向对象的编程语言,它使用类和对象。 C 编程是一种面向过程的编程语言。
C++ 遵循自底向上的编程方法 C 遵循自顶向下的方法
C++ 是 C 编程语言的超集 C 是 C++ 的子集
C++ 更安全,因为它支持数据隐藏,有助于防止攻击 C 不支持数据隐藏,更容易受到攻击
C++ 支持函数重载和运算符重载 C 没有此功能
C++ 包含比 C 编程语言更多的关键字 (52) C 编程只有 32 个关键字
C++ 支持友元函数和虚函数 C 不支持友元函数或虚函数
C++ 拥有引用变量 C 没有引用变量

 

C++ 中的类可以定义为用户定义的数据类型,它具有一些数据成员和数据函数,这些成员和函数使用 private、public 或 protected 进行定义。

简单来说,我们可以说类是数据及其相关函数的集合,可以通过一个名称调用。

类将使用关键字“class”声明,我们可以在 C++ 中声明任意数量的类。

 

类可以在 C++ 中使用关键字 class 声明,它可以包含一些数据成员和相关函数。

Class teachers

{

    // 数据成员

    // 函数

}

C++ 中的对象是类的实例。对象是从类创建的,该类将一些数据和一些函数组合在一起形成一个自包含的单元。

对象能够代表一个项目、一个人或一些其他项目。对象能够对类中定义的数据和函数进行操作。对象变量不占用任何内存空间,它分配在堆内存中。

在 C++ 中,我们有三种不同的方法来声明对象

  1. 使用默认构造函数
  2. 使用带参数的构造函数
  3. 使用复制构造函数

 

C++ 中的访问修饰符用于定义类成员的可访问性。它定义了如何访问类范围之外的类数据。

类有三种类型的访问修饰符,它们是

  1. Public
  2. Private
  3. Protected

继承是面向对象语言的一个特性,它有助于消除代码冗余并提供代码重用性。通过继承,我们可以将一个类的属性用于另一个类,这意味着一个新类是从旧类派生出来的,并具有旧类的属性。

  • 派生类: 从旧类派生出来的类称为派生类。
  • 基类: 旧类称为基类

 

封装是将类的数据及其函数绑定到一个单一包装中的方法,这样如果我们将数据成员的访问修饰符设置为 private,则外部函数无法访问类内部的数据成员。

使用封装,只有类内部的函数才能访问类的数据。示例:网上银行登录 ID 和密码。

抽象是隐藏非必要细节以避免外部函数访问的过程。通过抽象,它只显示必要的细节,避免了所有实现细节。

示例:假设我们点击发送按钮发送消息。它只显示消息已发送,而不显示如何发送该消息的细节,这就是抽象的一个示例。

 

C++ 中的数据绑定是将数据以及相关的用户界面和函数封装到单个名称中的过程。

顾名思义,多态性意味着多种形式。在 C++ 中,如果存在多个同名但功能不同的函数,我们就可以称之为多态性。

多态性有两种类型

  1. 静态多态性可以称为早期绑定。它也可以称为编译时多态性,这意味着多态性在编译时实现。静态多态性的一个示例是方法重载。
  2. 动态多态性可以称为后期绑定。它也称为运行时多态性,因为它的函数调用在运行时实现。动态多态性的一个示例是函数重载。

C++ 中有三种类型的访问修饰符,它们是

Private: 类的私有成员数据不能被该类之外的任何函数访问。即使子类函数也无法访问父类成员数据。

Protected: 它比 private 更具可访问性,子类函数可以访问父类的成员数据。

Public: 公有类数据可以被程序中的任何函数访问。公有类数据成员是全局可访问的。

C++ 中使用的基本数据类型是

  • Bool: 布尔操作,如是或否
  • Int: 整型值
  • Char: 字符值
  • Float: 浮点十进制值
  • Double: 大尺寸浮点值

派生数据类型

  • 数组
  • 指针

枚举数据类型

  • enum

用户定义数据类型

  • 结构体

 

命名空间用于在程序中安排大量的类,以避免混淆并方便处理程序。

命名空间通过将标识符放在不同的命名空间中来帮助 C++ 程序员消除名称冲突。

命名空间通过将同名但不同任务的程序代码放在不同的命名空间中来帮助消除程序的歧义。

命名空间实际上从逻辑上划分了程序,它还有助于定义不同标识符(如变量、类等)的范围

在 C++ 中,令牌可以是关键字、标识符、字面量、常量或符号中的任何一种。

C++ 中的关键字 volatile 用于声明一个变量随时可能快速改变。它告诉编译器此类变量的值可以随时更改。

C++ 中的存储类用于提供程序中变量或函数的可见性生命周期

可见性: 数据或变量可访问的代码的类或部分。

生命周期: 变量在 C++ 程序中可访问和活动的时间。

C++ 中有五种存储类,它们是

Auto: 局部变量,在函数块内部声明和访问,最初有一些垃圾值

Register: 局部变量,在函数内部声明和访问,最初有一些垃圾值。

Extern: 全局变量,在整个程序中声明和访问,最初为零值

Static: 局部变量,但在整个程序中可访问,最初为零值。

Mutable: 局部变量,在类内部声明和访问,最初有一些垃圾值。

在 C++ 中,如果我们想在满足特定条件之前运行特定代码段有限或无限次,则使用循环函数。循环函数内部的代码段必须在大括号 {} 中。

C++ 中的循环类型有

  • While
  • For
  • Do-while

C++ 中的函数由以下部分组成,形成一个结构,它们是

  1. 返回类型
  2. 函数名
  3. 参数
  4. 函数体

C++ 中的运算符是一个符号或操作数,它告诉编译器执行特定的数学或逻辑操作。

在 C++ 中,有不同的运算符可用,例如

  • 算术运算符
  • 逻辑运算符
  • 增量运算符
  • 赋值运算符
  • 等等

字符串是由字符组成的数组,这些字符构成以符号“\0”结尾或终止的单词

C++ 中的引用变量有点类似于 C 编程中的指针概念。它可以定义为声明为已存在变量的另一个名称的变量。

程序运行时活跃的错误或 bug 称为异常,处理该错误称为异常处理。

在 C++ 中,我们有 Try Catch 和 Throw 方法进行异常处理。

  • Try: 帮助我们定位异常活跃的代码部分
  • Catch: 它将通过异常处理程序捕获异常。
  • Throw: 如果在执行程序时发生错误,这将有助于抛出异常。

C++ 中有五种类型的函数可用,它们是

  • 简单函数
  • 静态函数
  • 常函数
  • 内联函数
  • 友元函数

决策语句是条件语句,有助于在程序中做出决策。C++ 支持

  • if 语句
  • switch 语句
  • 条件运算符

在 C++ 中,结构体与类的概念几乎相似,但与类有一些区别

结构体
在类内部,所有成员数据默认都是私有的 在结构体的情况下,所有数据成员默认都是公有的。

 

 

运算符重载是静态多态性的一个示例,它对于对用户定义数据类型进行操作至关重要。

借助运算符重载,我们可以为与用户定义数据类型一起使用的运算符分配特殊含义。

构造函数是一个函数,当创建一个与类同名的对象时,该函数会自动创建。

构造函数没有返回值,并且有三种类型的构造函数可用

  • 默认构造函数
  • 带参数的构造函数
  • 复制构造函数

我们知道在 C++ 中,父类称为基类,子类称为派生类。虚函数是基类中的一个函数,期望在派生类中重新定义以创建多态性。

虚函数使用关键字 virtual 声明。

当一个类被声明为友元时,它可以访问友元类的所有成员数据,无论其访问修饰符是 private、public 还是 protected。

友元函数类似于友元类,友元函数可以访问友元函数的所有 public、private 和 protected 成员。

如果我们在 C++ 中使用内联函数,编译器将在编译时找到该函数调用代码的地方放置该函数代码。

内联函数的主要用途是在执行程序时避免函数调用过程。

C++ 中的析构函数是我们关闭函数或程序结束时需要删除对象时调用的函数。析构函数是帮助删除或移除对象的函数。

析构函数与构造函数的作用相反,构造函数有助于创建对象。与构造函数一样,析构函数也会自动调用。

 

C++ 中的静态成员是使用关键字 static 声明的类成员。静态成员只有一个副本,并且可以被所有对象访问,无论从该类创建了多少个对象。如果一个类的成员定义为 static,那么它的内存将一直分配到程序结束。

多线程定义为并行执行多个进程的能力。多线程能力使编程语言更高效、更强大。C++ 中有两种类型的多线程,它们是

基于进程:在这种多线程类型中,它支持并行执行两个或更多程序。

基于线程:在这种多线程类型中,它支持单个程序的两个或更多线程并行运行。它将程序拆分为线程。

C++ 中的向上转型是将派生类引用变量或指针转换为基类引用变量或指针的过程。

C++ 中的向下转型是向上转型的反向操作,它将基类引用变量或指针转换为派生类指针或引用变量。向下转型是比向上转型相对更困难的过程。

在编译开始之前,有一些以“#”符号开头的指令,用于向编译器提供一些编译器必须预处理的信息,这些指令称为预处理器。

C++ 中的复制构造函数是一个重载构造函数,它有助于将一个对象的成员数据复制到另一个对象。这意味着复制构造函数用于使用同一类的另一个对象来初始化对象。

'==' 运算符称为“等于”运算符,它检查左侧值和右侧值是否相同。如果相同,则返回 true,否则返回 false。

'=' 运算符称为“赋值运算符”,它将右侧值赋给左侧变量。

它们都是 C++ 中的循环结构,用于在满足条件之前执行一段代码一定或不确定次数。但是 while 循环和 do-while 循环的区别在于

  • while 循环是入口控制循环,这意味着在进入循环之前会检查条件。如果条件不满足,循环甚至不会执行一次。
  • do while 循环是出口控制循环,这意味着只有在循环执行后才会检查条件。在这种情况下,即使条件不满足,循环也会执行一次。

 

前缀和后缀表达式取决于增量是如何对表达式进行的,是在值赋值之前还是之后。

  • 前缀: 在前缀表达式中,增量在值赋值给表达式之前完成。例如 ++i。
  • 后缀: 在后缀表达式中,增量在值赋值给表达式之后完成。例如 i++。

在 C++ 中,当使用按值调用函数调用方法时,在函数调用期间,实际参数的副本会传递给函数内部的形式参数。

在进行按值调用方法时,实际参数是安全的,并且在函数内部的形式参数发生变化时不会改变。

 

C++ 中的指针是包含其他变量地址的变量。指针也称为其他变量的定位器。

C++ 中的指针具有数据类型,并且必须与指针指向的变量数据类型匹配。例如,整数指针可以指向整数数据类型变量。

作用域解析运算符,由符号“::”表示,用于将函数与其类链接起来。它还用于在存在与全局变量同名的局部变量时使用全局变量。作用域解析运算符还用于定义类外部的函数。

C++ 中的可变类说明符用于更改类的成员变量值,即使其对象在执行期间是常量类型。

简单来说,可变对象的值即使在创建后也可以随时更改。

在 C++ 中,浅拷贝是通过完整复制所有成员数据并创建对象的副本来完成的。

复制所有成员数据以及不在该对象中但由该对象处理的资源内存位置称为深拷贝。

在 C++ 中,如果函数没有函数体且被赋值为零,则该函数被称为纯虚函数。

C++ 中的类如果至少包含一个纯虚函数,则该类被称为抽象类。

在 C++ 中,我们可以使用数据类型 wchar_t 存储宽字符。

函数重载可以描述为两个或多个同名但在同一作用域中具有不同参数的函数。C++ 支持此类函数,并称之为函数重载。

标准流用于 C++ 中的输入和输出相关操作,它们是

  • cin
  • cout
  • cerr
  • clog

在 C++ 中,有不同的方法可以分配动态内存,我们可以使用“new”运算符分配动态内存。

“delete”运算符有助于释放在使用“new”运算符时分配的动态内存。

“new”运算符用于动态分配内存空间。

C++ 中的 This 指针是一个持有当前活跃对象地址的指针。This 指针指向类的当前运行实例

C++ 中的块作用域变量是只在块中具有作用域的变量。我们可以在块中的任何位置声明变量。

C++ 中的命令行参数是我们运行时以字符串形式从命令行提供给主程序的参数。

C++ 中数组的基地址是数组的起始地址,由 array[0] 表示。

假设我们需要一个经常使用的变量,那么它必须使用寄存器存储说明符声明。

当变量声明为寄存器存储说明符时,它存储在 CPU 寄存器中,可以在程序运行时快速访问。

如果 C++ 中的类至少包含一个其他类类型的变量,则称其为容器类。

在 C++ 中,我们可以在程序运行时从命令行将参数传递给主程序,这称为命令行参数。

在 C++ 中,sizeof 运算符用于计算数据类型、类或对象的大小。

在 C++ 中,指针上允许的操作有限,它们是

  1. 数学运算 加法和减法
  2. 比较运算

C++ 中的递归定义为函数本身调用有限或无限次的函数。

delete 用于删除或释放内存空间,而 delete[] 用于删除或释放为数组分配的内存位置。

C++ 中的 cin 是一个 istream 类对象,用于使用键盘等标准输入设备从用户那里获取输入。

cout 是 C++ istream 类的一个对象,用于使用显示器等标准输出设备向用户显示输出。

实际参数是在函数调用时必须传递给调用函数的实际值或参数。

形式参数是调用函数中的参数,当函数调用发生时,它接受实际参数。

C++ 中的 $undef 用于取消定义已存在的宏定义。

在 C++ 中,STL 是标准模板库的缩写。

  • 数组是相同数据类型的D数据集合。而列表是不同数据类型的D数据集合。
  • 数组的内存分配是静态的,而列表的内存分配是动态的。

 

从 DLL 导出函数有两种方法,

  • 使用 DLL 的类型库
  • 从 DLL 获取函数引用

C++ 中的空指针是指没有与其关联的数据类型的引用变量。空指针可以指向任何数据类型。

溢出错误发生在某些数学计算中,当数学运算的结果大于为该结果分配的内存时,就会发生溢出错误。

C++ 中的 STL 有四个组件,它们是

  • 容器
  • 算法
  • 迭代器
  • 函数

类模板可以定义为创建泛型类或函数的方法或原型。我们使用关键字 template 定义类模板。

注释是代码段中的书面信息,编译器会忽略它们,但对程序员理解该代码段的目的很有帮助。C++ 中使用“#”编写注释。

变量的作用域定义为声明和访问该变量的代码部分。

  • 局部作用域: 在类或代码块内部定义和访问的变量称为局部作用域变量。该变量不能从其他任何地方访问。
  • 全局作用域: 如果变量可以在程序中的任何地方访问,无论类或代码块如何,则称其具有全局作用域。

C++ 中的常量使用预处理器指令“#define”定义。

如果我们想在不使用作用域解析运算符的情况下引用命名空间中的成员名称,我们可以使用“using”声明。

转换构造函数是接受不同类型参数的构造函数,它用于将一种类型转换为另一种类型

显式构造函数是使用关键字“explicit”声明的转换构造函数。当我们声明显式构造函数时,编译器会显式保留该构造函数用于转换目的。它不用于实现隐式类型转换。

不能重载的运算符有:

sizeof:大小运算符

  • . :点运算符
  • .* :解引用运算符
  • -> 成员解引用运算符
  • :: :作用域解析运算符
  • ?: :条件运算符

C++ 编程语言由 Bjarne Stroustrup 于 1985 年创建。C 编程语言是 C++ 的子集,C++ 是 C 编程语言的超集。