C++ 在今天仍然像它在 80 年代中期出现时一样重要。命令式、面向对象的编程语言被广泛用作通用编程语言。因此,一些工作要求候选人对 C++ 有深刻的理解。如果你希望进一步提高 C++ 语言技能,这里有一些最好的C++ 教程可以帮助你。
最佳C++常见面试题和答案合集
如果你正在准备一份强调 C++ 的工作角色,那么这里有 20 个最重要的 C++ 面试问题,用于自我评估你的 C++ 面试准备:
初级面试问题
问题:定义C++?
答:C++ 是一种计算机编程语言,它是 C 的超集,其中在 C 语言中添加了附加功能。
C++常见面试题有哪些:我们可以调用 C++ OOPS 吗?为什么?
答:是的,C++ 可以称为 OOPS。OOPS 的完整形式是面向对象的编程系统,这意味着提供各种概念的应用的范式,包括数据绑定、多态性、继承和其他各种概念。
问题:在 C++ 中定义类?
答:类是指用户自定义数据类型的设计。它反映了不同的实体、属性和动作。
问题:在 C++ 中定义对象?
答:对象是类的一个实例。一个对象可以有字段、方法、构造函数和相关的。例如,现实生活中的自行车是一个对象,但它具有各种特征,例如刹车、颜色、尺寸、设计等,这些都是同类的实例。
问题:在 C++ 中定义封装?
C++面试题解析:封装是将类中的数据和函数绑定在一起的过程。出于安全原因,它用于防止直接访问数据。为此目的应用类的功能。例如,客户的网上银行设施只允许具有所需登录 ID 和密码的授权人员访问。这也仅适用于他/她在银行数据源中的部分信息。
问题:什么是 C++ 中的抽象?
答:C++ 中的抽象隐藏了内部实现并仅显示所需的详细信息。例如,当你通过电子邮件发送重要信息时,此时仅使用写入和单击发送选项。此结果只是显示的成功消息,以确认你的电子邮件已发送。但是,通过电子邮件传输数据所遵循的过程不会显示,因为它对你没有用。
问题:简述C++中继承的概念。
答:C++ 允许类从其他类继承一些常用的状态和行为。这个过程称为继承。
问题:在 C++ 中定义访问说明符及其各种类型
回答:访问说明符提供了如何定义类成员(即函数和变量)在类范围之外访问的方式。C++ 中有三种类型的访问说明符:
- Private – 此类成员不能在声明它们的类之外访问,并且只能在同一个类中访问。甚至子类也无法访问其父类的私有成员。
- protected ——除了声明它们的类之外,子类还可以访问其父类的受保护成员。
- Public - 声明为 public 的类成员可以在整个程序(代码)中访问
问题:定义命名空间?
答: 命名空间用于解决标识符的名称冲突,通过将它们放在不同的命名空间下来完成。这样,它有助于不同代码的逻辑划分。
问题:定义一个类模板?
回答:类模板是泛型类的名称。关键字模板用于定义类模板。
问题:关键字“Volatile”的作用是什么?
答:“Volatile”是一个函数,它有助于声明特定变量是 volatile,从而指示编译器从外部更改变量——这样,可以避免编译器对变量引用的优化。
问题:在 C++ 中定义存储类?点个名?
答:C++ 中的存储类特别类似于生命甚至符号的作用域,包括变量、函数等。 C++ 中的一些存储类名称包括 mutable、auto、static、extern、register 等。
C++常见面试题和答案合集:我们可以在 C++ 中使用递归内联函数吗?
答: 即使可以在 C++ 中从自身内部调用内联函数,但编译器可能不会生成内联代码。这是因为编译器不会在编译时确定递归的深度。
尽管如此,具有良好优化器的编译器能够内联递归调用,直到在编译时固定某个深度,并在实际深度超过运行时间的情况下在编译时插入非递归调用。
问题:在 C++ 中定义内联函数?写出它的语法。C++ 编译器是否有可能忽略内联?
答:为了减少函数调用开销,C++ 提供了内联函数。顾名思义,内联函数在调用时会在行中展开。
一旦内联函数被调用,整个代码就会被插入或替换在内联函数调用的特定点。替换由 C++ 编译器在编译时完成。小的内联函数可能会提高程序效率。
典型的内联函数的语法是:
Inline return-type function-name(parameters)
{
// Function code goes here
}
由于内联是一个请求,而不是一个命令,编译器可以忽略它。
问题:解释“this”指针?
答:'this' 指针是一个常量指针,它保存当前对象的内存地址。它作为隐藏参数传递给所有非静态成员函数调用。此外,它可用作所有非静态函数体内的局部变量。
由于静态成员函数甚至可以在没有任何对象的情况下调用,即使用类名,“this”指针对它们不可用。
C++常见面试题有哪些:C 和 C++ 之间最重要的区别是什么?
回答:
- C++ 支持引用,而 C 不支持
- 友元函数、函数重载、继承、模板和虚函数等特性是 C++ 固有的。这些在 C 编程语言中不可用。
- 在 C 中,异常处理以传统的 if-else 风格进行。另一方面,C++ 在语言级别提供对异常处理的支持。
- C中主要使用的输入和输出分别是scanf()和printf()。在 C++ 中,cin 是标准输入流,而 cout 是标准输出流。
- 虽然 C 是一种过程编程语言,但 C++ 提供了对过程和面向对象编程方法的支持。
问题:为什么我们需要 Friend 类和函数?
答:有时,需要允许特定类访问类的私有成员或受保护成员。解决方案是友元类,它可以访问声明为友元的类的protected 和private 成员。
与友元类类似,友元函数能够访问私有和受保护的类成员。友元函数既可以是全局函数,也可以是某个类的方法。
关于友元类和友元函数的一些要点:
- 友元不是遗传的。
- 友元不是相互的,即,如果某个名为 Friend 的类是另一个名为 NotAFriend 的类的朋友,那么它不会自动成为 Friend 类的朋友。
- 程序中应限制友元类和友元函数的总数,因为过多可能会导致对单独类的封装概念的贬低,这是面向对象编程的内在和理想品质。
中级面试题
问题:解释c++中vTable和vptr的意义以及编译器如何处理它们
C++面试题解析:vTable 是一个包含函数指针的表。每个班级都有一个vTable。vptr 是一个指向 vTable 的指针。每个对象都有一个 vptr。为了维护和使用 vptr 和 vTable,C++ 编译器在两个地方添加了额外的代码:
- 在每个构造函数中- 此代码设置 vptr:
- 正在创建的对象
- 指向类的vTable
- 带有多态函数调用的代码——在进行多态调用的每个位置,编译器都会插入代码,以便首先使用基类指针或引用查找 vptr。一旦成功获取 vptr,就可以访问派生类的 vTable。使用 vTable 访问和调用派生类函数 show() 的地址。
问题:函数重载与运算符重载有何不同?
答:函数重载允许两个或多个具有不同类型和数量参数的函数具有相同的名称。另一方面,运算符重载允许重新定义运算符对用户定义类型的工作方式。
问题:是否可以在没有 main() 函数的情况下编译 C++ 程序?
回答:是的,这是可能的。但是,由于main()函数对于程序的执行来说是必不可少的,程序编译后就会停止,不会执行。
问题:什么是析构函数?
答:析构函数是类的成员函数。它与类名同名,并以波浪号为前缀。只要对象失去其作用域,它就可以自动执行。
问题:我们可以重载析构函数吗?
答:不可以,析构函数不能被重载,它是唯一没有参数的形式。
问题:默认构造函数是什么?
答:编译器为每个类提供一个构造函数,以防提供者不提供相同的构造函数。这是当程序员提供没有特定参数的构造函数而不是它被称为默认构造函数时。默认构造函数的代码可以在以下示例中显示。
// Cpp program to illustrate the
// concept of Constructors
#include <iostream>
using namespace std;
class construct {
public:
int a, b;
// Default Constructor
construct()
{
a = 10;
b = 20;
}
};
int main()
{
// Default constructor called automatically
// when the object is created
construct c;
cout << "a: " << c.a << endl
<< "b: " << c.b;
return 1;
}
问题:我们可以为我们的类提供一个默认构造函数吗?
答:不,我们不能为我们的类提供一个默认构造函数。当类类型中的变量设置为 null 时,意味着它从未被初始化并且结果将为零。
问题:关键字 struct 和 class 之间的主要区别是什么?
答:关键字struct默认用于类公共成员,关键字class默认用于类私有成员。
问题:比较一下 C++ 和 Java
回答:
- C++ 有析构函数,当对象被销毁时会自动调用它们。Java 有一种叫做自动垃圾收集的东西
- C++ 支持多重继承、运算符重载、指针、结构、模板和联合。Java 没有它们中的任何一个
- Java 有一个 Thread 类,该类被继承以创建新线程。C++ 没有对线程的内置支持
- 在 C++ 中,goto 语句提供了一种从某个位置跳转到同一函数中的某个标记语句的方法。Java中没有goto语句
- C++ 使用编译器运行和编译,将源代码转换为机器级语言。因此,它是平台相关的。另一方面,Java 编译器将源代码转换为与平台无关的 JVM 字节码。
问题:看看下面的 C++ 程序:
#include
using namespace std;
int main()
{
int numbers[5], sum = 0;
cout << "Enter 5 numbers: ";
for (int i = 0; i < 5; ++i)
{
cin >> numbers[i];
sum += numbers[i];
}
cout << "Sum = " << sum << endl;
return 0;
}
输出会是什么?
答:程序会要求用户输入 5 个数字,然后显示它们的总和。例如,
Enter 5 numbers: 22
25
32
46
66
Sum = 191
C++常见面试题和答案合集: 用代码示例解释虚拟函数和 C++ 中运行时多态的概念。
回答:任何伴随virtual关键字的函数都表现出虚函数的行为。与根据使用的指针或引用的类型调用的普通函数不同,虚拟函数是根据指向或引用的对象的类型调用的。
简单来说,虚函数在运行时解析,而不是更早。虚拟函数的使用也可以理解为利用运行时多态性的概念编写 C++ 程序。在 C++ 中编写虚函数的必要条件是:
- 一个基类
- 派生类
- 在两个类(即基类和派生类)中具有相同名称的函数
- 基类类型的指针或引用,分别指向或引用派生类的对象
一个演示使用虚函数(或运行时多态性)的例子是:
#include
using namespace std;
class Base {
public:
virtual void show() { cout<<" In Base \n"; }
};
class Derived: public Base {
public:
void show() { cout<<"In Derived \n"; }
};
int main(void) {
Base *bp = new Derived;
bp->show(); // <- Runtime Polymorphism in Action
return 0;
}
在上述程序中 bp 是一个 Base 类型的指针。调用 bp->show() 调用派生类的 show() 函数。这是因为 bp 指向派生类的对象。
问题:C++ 中的结构与类有何区别?
答:C++ 中的类和结构之间有两个重要的区别。这些是:
- 从类或其他结构派生结构时,基类或结构的默认访问说明符是 public。相反,派生类时,默认访问说明符是私有的。
- 虽然结构的成员默认是公共的,但类的成员默认是私有的
问题:C++ 中的静态成员是什么意思?
答:用static关键字表示,静态成员被分配了存储空间,在静态存储区中,在程序生命周期内只分配一次。关于静态成员的一些重要事实是:
- 任何静态成员函数都不能是虚拟的
- 静态成员函数没有“this”指针
- const、const volatile 和 volatile 声明不可用于静态成员函数
C++常见面试题有哪些:定义参考变量?
答:C++ 中的引用变量是给现有变量的名称。变量名和引用变量点在 C++ 中共享相同的内存位置,这有助于使用引用变量更新原始变量。代码可以在以下示例中显示。
#include<iostream>
using namespace std;
int main()
{
int x = 10;
// ref is a reference to x.
int& ref = x;
// Value of x is now changed to 20
ref = 20;
cout << "x = " << x << endl ;
// Value of x is now changed to 30
x = 30;
cout << "ref = " << ref << endl ;
return 0;
}
高级面试问题
问题:定义 C++ 中使用的复制构造函数及其通用函数原型。另外,解释调用它的各种场景。
C++面试题解析:使用同一类的另一个对象初始化对象的成员函数在 C++ 中称为复制构造函数。复制构造函数也可以设为私有。在以下 4 种情况中的任何一种情况下,都可能调用 Copy Constructor:
- 编译器生成临时对象
- 一个对象是构造的或基于同一类的另一个对象
- 类的一个对象按值返回
- 类的对象作为参数按值传递(即传递给函数)
复制构造函数的通用函数原型是:
ClassName (const ClassName &old_obj);
Point(int x1, int y1) { x=x1; y=y1;}
Point(const Point &p2) { x=p2.x; y=p2.y; }
问题:观察以下代码片段:
int i = 5;
int j = i++;
执行后,I 和 j 的值是多少?解释你的答案。
答: 执行上述代码后,i 和 j 将分别为 6 和 5。为了理解输出,了解一元“++”运算符和递减“--”运算符在 C++ 中的工作原理很重要。
当这些运算符中的任何一个位于变量之前时,首先修改变量的值,然后使用修改后的值。但是,当两个运算符中的任何一个跟随一个变量时,首先使用该值,然后对其进行修改。
因此,在上面的代码中,j 被设置为未修改的值 5,然后 i 递增存储 6。
问题:看下面两个打印向量的代码示例:
Sample Code 1:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); itr++) {
itr->print();
}
Sample Code 2:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
itr->print();
}
使用一个比另一个有什么优势吗?
答: 虽然两个代码会生成相同的输出,但示例代码 2 是一个性能更好的选项。这是因为后增量 'itr++' 运算符比预增量 '++itr' 运算符更昂贵。
后增量运算符在继续增加元素并返回副本之前生成元素的副本。此外,大多数编译器会通过将示例代码 1 隐式转换为示例代码 2 来自动优化示例代码 1。
问题:假设你有 n 个学生的 GPA(平均成绩),你需要使用 C++ 存储和显示它。你能写一个程序来完成这个任务吗?
回答:
#include
#include
using namespace std;
int main()
{
int num;
cout << "Enter the total number of students: ";
cin >> num;
float* ptr;
ptr = new float[num];
cout << "Enter the GPA of students." << endl;
for (int i = 0; i < num; ++i)
{
cout << "Student" << i + 1 << ": ";
cin >> *(ptr + i);
}
cout << "\nDisplaying GPA of students." << endl;
for (int i = 0; i < num; ++i) {
cout << "Student" << i + 1 << " :" << *(ptr + i) << endl;
}
delete [] ptr;
return 0;
问题:什么是可变存储类说明符?如何使用它们?
答案:可变存储类说明符仅应用于类的非静态和非常量成员变量。它用于通过声明来改变常量类对象的成员。这可以通过使用存储类说明符来完成。
问题:浅拷贝和深拷贝有什么区别?
答:浅拷贝和深拷贝之间的区别可以表述如下。
浅拷贝 | 深拷贝 |
它允许从一个对象到另一个对象逐位转储内存。 | 它允许复制字段,这是按字段从一个对象到另一个对象完成的。 |
它是通过使用复制指导员和重载赋值运算符来实现的。 | 它用于浅拷贝目的。 |
问题:在 C++ 中定义抽象类?
答:C++ 中的抽象类称为基类,它至少具有一个纯虚函数。在这样的函数中,一个人不能实例化一个抽象类。这样,在类声明中的虚成员函数声明期间,通过使用等于零的纯说明符将抽象类定义为纯虚函数。示例代码示例如下所示。
// An abstract class
class Test
{
// Data members of class
public:
// Pure Virtual Function
virtual void show() = 0;
/* Other members */
};
题; 我们可以在 C++ 中有一个 String 原始数据类型吗?
答:不,我们不能在 C++ 中使用 String Primitive 数据类型。相反,我们可以从标准模板库 (STL) 获得一个类。
C++常见面试题和答案合集:在C++中我们可以使用访问说明符来实现数据隐藏吗?
答:是的,我们可以使用访问说明符来实现 C++ 中的数据隐藏。其中包括私有和受保护。
问题:定义块作用域变量?
答案:块作用域变量是使用 C++ 指定为块的变量,该变量可以在块内的任何位置声明。
问题:范围解析运算符的功能是什么?
答:范围解析运算符的功能包括以下内容。
- 它有助于解决各种全局变量的范围。
- 当函数在类之外定义时,它有助于将函数与类相关联。
作用域解析运算符的代码可以显示如下。
#include <iostream>
using namespace std;
int my_var = 0;
int main(void) {
int my_var = 0;
::my_var = 1; // set global my_var to 1
my_var = 2; // set local my_var to 2
cout << ::my_var << ", " << my_var;
return 0;
}
问题:关键字“Auto”的作用是什么?
答:关键字“Auto”默认用于各种局部变量,使函数自动工作。
C++常见面试题有哪些:在 C++ 中定义一个标记?举个例子?
答:标记是 C++ 程序中各种函数的名称。标记的示例包括关键字、符号、字符串文字、标识符、常量等。C 以外的 C++ 中标记的代码可以在下面的示例中显示。
asm bool catch class
const_cast delete dynamic_cast explicit
export false friend inline
mutable namespace new operator
private protected public reinterpret_cast
static_cast template this throw
true try typeid typename
using virtual wchar_t
问题: C++ 中多重继承出现的“钻石问题”是什么?用一个例子来解释。
C++面试题解析: C++ 中的菱形问题表示编程语言无法支持使用多重继承和层次继承的混合继承。
假设我们有一所大学,有一些教职员工和一些研究生。在这种情况下,一个简单的继承方案可能有不同类型的人担任不同的角色。但是,它们都继承自同一个 Person 类。
Person 类定义了一个抽象的 getRole() 方法,然后该方法将被其子类覆盖以返回正确的角色类型。到目前为止,事情很简单,但是,如果我们希望模拟助教或助教的角色,那么事情就会变得很奇怪。
助教既是学生又是教职员工。这将产生菱形问题,如下图所示:
该问题生成一个类似于菱形的继承图,因此得名菱形问题。
助教应该继承哪个 getRole() 实现?研究生还是教员?一个潜在的答案可能是让助教类覆盖 getRole() 方法并返回一个新定义的角色,比如 TA。
然而,这样的答案也远非完整,因为它会隐藏助教既是教员又是研究生的事实。
结论
本文还介绍了一些 C++ 编码面试问题和答案,以帮助你。教程是一种极好的学习方式。此外,你还可以访问其他资源。不要错过他们。这里有一些重要的 C++ 教程,可以加强你的 C++ 知识。
除了充分了解求职面试中可能会问到的所有概念之外,还需要更多的知识。风度和举止也是面试官关注的。所以,要清楚准确,不要跑题。