概述
以下是Top 30 C++面试题及答案,从基础到高级分类,非常适合工作面试和技术轮次。
基础级别 (1–10)
1.什么是C++?
C++是由Bjarne Stroustrup开发的通用、面向对象编程语言。它支持过程式和面向对象编程,使其成为多范式语言。
2.C++的主要特性是什么?
- OOP支持(类、继承、多态)
- 函数和运算符重载
- 模板
- 异常处理
- STL(标准模板库)
3.C和C++之间有什么区别?
特性CC++范式过程式多范式OOP否是函数重载否是封装否是
4.iostream的用途是什么?
#include <iostream>用于C++中使用cin和cout进行输入/输出操作。
5.cin和cout之间有什么区别?
- cin用于输入。
- cout用于输出。
两者都是iostream库的一部分。
6.C++中的数据类型有哪些?
- 基本类型:int、float、double、char、bool
- 派生类型:array、pointer
- 用户定义类型:struct、class、union、enum
7.==和=之间有什么区别?
- =是赋值运算符。
- ==是比较运算符。
8.C++中的指针是什么?
指针是存储另一个变量内存地址的变量。
9.什么是引用变量?
引用变量是使用&创建的另一个变量的别名。
int a = 10;
int &ref = a;
10.什么是构造函数?
构造函数是在创建对象时自动调用的特殊函数。
中级级别 (11–20)
11.什么是函数重载?
函数重载允许具有相同名称但不同参数的多个函数。
12.什么是运算符重载?
运算符重载允许您为运算符定义自定义行为。
class A {
int x;
public:
A(int i): x(i) {}
A operator+(A a) { return A(x + a.x); }
};
13.C++中的继承是什么?
继承是一个类(子类)继承另一个类(父类)属性的过程。
14.继承的类型有哪些?
- 单继承
- 多继承
- 多级继承
- 层次继承
- 混合继承
15.什么是多态?
多态意味着具有多种形式。它允许相同的函数名对不同的输入表现出不同的行为。
16.编译时多态和运行时多态之间有什么区别?
- 编译时:函数重载、运算符重载
- 运行时:虚函数
17.什么是虚函数?
虚函数允许运行时多态,使用virtual关键字声明。
18.什么是纯虚函数?
virtual void show() = 0;
它使类成为抽象类,派生类必须重写它。
19.什么是封装?
封装是通过将数据和函数包装到单个单元(类)中来隐藏数据。
20.什么是抽象?
抽象意味着隐藏内部细节,只显示相关信息。
高级级别 (21–30)
21.什么是标准模板库(STL)?
STL是通用类和函数的库,如vector、map、set、queue等。
22.类和结构体之间有什么区别?
特性类结构体默认访问权限privatepublicOOP支持是部分
23.什么是访问说明符?
- public:在任何地方都可访问
- private:仅在类内可访问
- protected:在类内和派生类内可访问
24.构造函数的类型有哪些?
- 默认构造函数
- 参数化构造函数
- 拷贝构造函数
25.什么是析构函数?
析构函数是使用~ClassName()的特殊函数,用于释放内存。
26.new和malloc()之间有什么区别?
- new调用构造函数;malloc不调用
- new是C++;malloc是C
27.什么是this指针?
它是指向当前对象的指针。
28.C++中的智能指针是什么?
智能指针自动管理内存(shared_ptr、unique_ptr、weak_ptr)。
29.什么是异常处理?
使用try、catch、throw处理运行时错误的机制。
30.C++中的模板是什么?
模板允许编写通用代码。
template <typename T>
T add(T a, T b) {
return a + b;
}
详细代码示例
基础概念示例
#include <iostream>
#include <string>
using namespace std;
// 1. 基本数据类型和变量
void basicDataTypes() {
int integer = 10;
float floating = 3.14f;
double doubleNum = 3.14159;
char character = 'A';
bool boolean = true;
cout << "Integer: " << integer << endl;
cout << "Float: " << floating << endl;
cout << "Double: " << doubleNum << endl;
cout << "Char: " << character << endl;
cout << "Bool: " << boolean << endl;
}
// 2. 指针和引用
void pointersAndReferences() {
int x = 10;
int* ptr = &x; // 指针
int& ref = x; // 引用
cout << "Original value: " << x << endl;
cout << "Pointer value: " << *ptr << endl;
cout << "Reference value: " << ref << endl;
// 通过指针修改值
*ptr = 20;
cout << "After pointer modification: " << x << endl;
// 通过引用修改值
ref = 30;
cout << "After reference modification: " << x << endl;
}
// 3. 函数重载
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
string add(string a, string b) {
return a + b;
}
面向对象编程示例
#include <iostream>
#include <string>
using namespace std;
// 基类
class Animal {
protected:
string name;
int age;
public:
// 构造函数
Animal(string n, int a) : name(n), age(a) {
cout << "Animal constructor called" << endl;
}
// 虚函数
virtual void makeSound() {
cout << "Some animal sound" << endl;
}
// 纯虚函数
virtual void move() = 0;
// 析构函数
virtual ~Animal() {
cout << "Animal destructor called" << endl;
}
};
// 派生类
class Dog : public Animal {
private:
string breed;
public:
// 构造函数
Dog(string n, int a, string b) : Animal(n, a), breed(b) {
cout << "Dog constructor called" << endl;
}
// 重写虚函数
void makeSound() override {
cout << name << " says: Woof!" << endl;
}
// 实现纯虚函数
void move() override {
cout << name << " is running" << endl;
}
// 析构函数
~Dog() {
cout << "Dog destructor called" << endl;
}
};
// 运算符重载示例
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 运算符重载
Complex operator+(const Complex& c) const {
return Complex(real + c.real, imag + c.imag);
}
Complex operator-(const Complex& c) const {
return Complex(real - c.real, imag - c.imag);
}
// 输出运算符重载
friend ostream& operator<<(ostream& out, const Complex& c) {
out << c.real << " + " << c.imag << "i";
return out;
}
};
模板和STL示例
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <memory>
using namespace std;
// 函数模板
template<typename T>
T findMax(T a, T b) {
return (a > b) ? a : b;
}
// 类模板
template<typename T>
class Stack {
private:
vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) {
throw runtime_error("Stack is empty");
}
T element = elements.back();
elements.pop_back();
return element;
}
bool isEmpty() const {
return elements.empty();
}
size_t size() const {
return elements.size();
}
};
// STL容器使用示例
void stlExamples() {
// Vector
vector<int> numbers = {1, 2, 3, 4, 5};
numbers.push_back(6);
// Map
map<string, int> scores;
scores["Alice"] = 95;
scores["Bob"] = 87;
scores["Charlie"] = 92;
// Set
set<int> uniqueNumbers = {1, 2, 2, 3, 3, 4};
// 算法
sort(numbers.begin(), numbers.end());
auto maxElement = max_element(numbers.begin(), numbers.end());
cout << "Max element: " << *maxElement << endl;
}
// 智能指针示例
void smartPointerExamples() {
// unique_ptr
unique_ptr<int> ptr1(new int(10));
cout << "Unique ptr value: " << *ptr1 << endl;
// shared_ptr
shared_ptr<string> ptr2 = make_shared<string>("Hello");
shared_ptr<string> ptr3 = ptr2; // 引用计数增加
cout << "Shared ptr value: " << *ptr2 << endl;
cout << "Reference count: " << ptr2.use_count() << endl;
// weak_ptr
weak_ptr<string> weakPtr = ptr2;
cout << "Weak ptr expired: " << weakPtr.expired() << endl;
}
异常处理示例
#include <iostream>
#include <stdexcept>
using namespace std;
// 自定义异常类
class DivisionByZeroException : public exception {
public:
const char* what() const noexcept override {
return "Division by zero is not allowed";
}
};
// 异常处理函数
double divide(double a, double b) {
if (b == 0) {
throw DivisionByZeroException();
}
return a / b;
}
// 异常处理示例
void exceptionHandlingExample() {
try {
double result = divide(10, 0);
cout << "Result: " << result << endl;
}
catch (const DivisionByZeroException& e) {
cout << "Caught exception: " << e.what() << endl;
}
catch (const exception& e) {
cout << "Caught general exception: " << e.what() << endl;
}
catch (...) {
cout << "Caught unknown exception" << endl;
}
}
// RAII(资源获取即初始化)示例
class ResourceManager {
private:
int* resource;
public:
ResourceManager() : resource(new int(0)) {
cout << "Resource acquired" << endl;
}
~ResourceManager() {
delete resource;
cout << "Resource released" << endl;
}
void useResource() {
cout << "Using resource: " << *resource << endl;
}
};
高级特性示例
#include <iostream>
#include <functional>
#include <thread>
#include <chrono>
using namespace std;
// Lambda表达式示例
void lambdaExamples() {
// 基本lambda
auto add = [](int a, int b) { return a + b; };
cout << "Lambda result: " << add(5, 3) << endl;
// 捕获列表
int multiplier = 10;
auto multiply = [multiplier](int x) { return x * multiplier; };
cout << "Multiply result: " << multiply(5) << endl;
// 可变lambda
int counter = 0;
auto increment = [&counter]() mutable { return ++counter; };
cout << "Counter: " << increment() << endl;
cout << "Counter: " << increment() << endl;
}
// 函数对象示例
class Adder {
private:
int value;
public:
Adder(int v) : value(v) {}
int operator()(int x) const {
return x + value;
}
};
// 移动语义示例
class MoveExample {
private:
int* data;
size_t size;
public:
// 构造函数
MoveExample(size_t s) : size(s) {
data = new int[size];
cout << "Constructor called" << endl;
}
// 拷贝构造函数
MoveExample(const MoveExample& other) : size(other.size) {
data = new int[size];
for (size_t i = 0; i < size; ++i) {
data[i] = other.data[i];
}
cout << "Copy constructor called" << endl;
}
// 移动构造函数
MoveExample(MoveExample&& other) noexcept
: data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
cout << "Move constructor called" << endl;
}
// 析构函数
~MoveExample() {
delete[] data;
cout << "Destructor called" << endl;
}
};
面试技巧
1. 准备阶段
- 复习C++基础语法和概念
- 练习编写面向对象代码
- 理解内存管理和指针
- 熟悉STL容器和算法
- 练习模板编程
2. 面试中
- 仔细阅读问题要求
- 先思考再编码
- 解释你的设计思路
- 考虑内存安全和性能
- 讨论代码的可维护性
3. 常见陷阱
- 忘记处理内存泄漏
- 忽略const正确性
- 不熟悉移动语义
- 缺乏对RAII的理解
- 忽略异常安全
总结
这30个C++面试题涵盖了从基础概念到高级特性的各个方面:
- 基础概念:数据类型、指针、引用、函数
- 面向对象编程:类、继承、多态、封装
- 高级特性:模板、STL、智能指针、异常处理
- 现代C++:Lambda表达式、移动语义、RAII
- 最佳实践:内存管理、性能优化、代码设计
掌握这些概念将帮助您在C++面试中表现出色,并在实际工作中编写高效、安全的代码。