C++基础知识总结(超详细整理)
1. C++语言核心特性
特性 | 描述 | 示例场景 |
---|---|---|
面向对象(OOP) | 支持类、继承、多态、封装,通过class 关键字定义对象类型。 |
设计一个Car 类,封装品牌、速度、加速方法 |
泛型编程(模板) | 使用template 可实现类型无关、可重用的算法和容器。 |
template<typename T> T max(T a, T b) |
性能可控 | 支持手动内存管理和低级操作,可精细控制性能开销。 | 使用new /delete 或RAII实现资源管理 |
兼容C语言 | 与C语言高度兼容,可调用C库函数,平滑迁移遗留C代码。 | 在C++中#include <stdio.h> 并使用printf |
标准库(STL) | 提供容器、算法、迭代器等丰富组件,简化常见数据结构与算法实现。 | 使用std::vector<int> 存储动态数组 |
RAII | 通过对象构造/析构管理资源,避免泄漏。 | std::lock_guard<std::mutex> 管理互斥锁 |
多范式支持 | 支持过程式、面向对象、泛型、函数式编程风格。 | 使用std::function 和lambda表达式 |
编译期检查与优化 | 模板和内联函数在编译期实例化和展开,可实现零开销抽象;编译器提供多种优化选项。 | inline 函数在调用处展开,消除函数调用开销 |
2. C++基本语法
2.1 标识符与关键字
- 标识符:字母、数字、下划线组合,且不能以数字开头;区分大小写;与关键字不冲突。
- 常用关键字示例:
int
,char
,class
,public
,private
,template
,virtual
,if
,for
,while
,return
。
2.2 注释
cpp
// 单行注释
/* 多行注释
可跨多行 */
2.3 基本数据类型
类型 | 大小(典型) | 取值范围 |
---|---|---|
char |
1 byte | -128 ~ 127 或 0 ~ 255 |
int |
4 bytes | -2^31 ~ 2^31-1 |
short |
2 bytes | -2^15 ~ 2^15-1 |
long |
8 bytes | -2^63 ~ 2^63-1 |
float |
4 bytes | 单精度浮点 |
double |
8 bytes | 双精度浮点 |
bool |
1 byte | true /false |
2.4 变量与常量
cpp
int x = 10; // 变量初始化
const double PI = 3.14159; // 常量声明
2.5 运算符
- 算术:
+
,-
,*
,/
,%
- 关系:
==
,!=
,<
,>
,<=
,>=
- 逻辑:
&&
,||
,!
- 位运算:
&
,|
,^
,~
,<<
,>>
- 赋值:
=
,+=
,-=
,*=
,/=
,%=
- 其他:
?:
(三元)、sizeof
、typeid
2.6 控制流
cpp
if (a > b) {
// ...
} else if (a == b) {
// ...
} else {
// ...
}
switch (c) {
case 0: doA(); break;
case 1: doB(); break;
default: doDefault();
}
for (int i = 0; i < n; ++i) {
// ...
}
while (cond) {
// ...
}
do {
// ...
} while (cond);
3. 指针与引用
3.1 指针
cpp
int a = 5;
int* p = &a; // p指向a
*p = 10; // 通过指针修改a的值
nullptr
表示空指针- 指针算术:
p + 1
指向下一个同类型元素
3.2 引用
cpp
int b = 20;
int& r = b; // r是b的引用
r = 30; // b变为30
- 引用必须初始化且不能重新绑定
4. 函数与重载
cpp
int add(int a, int b) {
return a + b;
}
// 函数重载
double add(double a, double b) {
return a + b;
}
- 默认参数:
void f(int x = 0)
- 内联函数:
inline int f() { return 0; }
- 递归函数:支持函数自己调用自身
5. 类与对象
5.1 类定义
cpp
class Person {
public:
Person(const std::string& name, int age)
: name(name), age(age) {}
void introduce() const {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}
private:
std::string name;
int age;
};
5.2 继承与多态
cpp
class Student : public Person {
public:
Student(const std::string& n, int a, const std::string& sid)
: Person(n, a), studentId(sid) {}
void introduce() const override {
Person::introduce();
std::cout << "ID: " << studentId << std::endl;
}
private:
std::string studentId;
};
- 虚函数:
virtual void func();
- 纯虚函数:
virtual void func() = 0;
- 抽象类:包含至少一个纯虚函数
6. 模板与STL
6.1 函数模板
cpp
template<typename T>
T Max(T a, T b) {
return a > b ? a : b;
}
6.2 类模板
cpp
template<typename T>
class Stack {
public:
void push(const T& x) { data.push_back(x); }
void pop() { data.pop_back(); }
private:
std::vector<T> data;
};
6.3 常用STL容器
std::vector
,std::list
,std::deque
std::map
,std::unordered_map
,std::set
- 算法:
std::sort
,std::find
,std::for_each
7. 内存管理与RAII
new
/delete
,new[]
/delete[]
- 智能指针:
std::unique_ptr
,std::shared_ptr
,std::weak_ptr
- RAII:资源获取即初始化,依赖析构自动释放
8. 异常处理
cpp
try {
mayThrow();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown error" << std::endl;
}
9. 输入输出
cpp
#include <iostream>
std::cout << "Hello" << std::endl;
std::cin >> x;
#include <fstream>
std::ifstream in("input.txt");
std::ofstream out("output.txt");
10. 编译与调试
- 常用命令:
g++ -std=c++17 main.cpp -o app
- 调试:
gdb
,valgrind
检测内存问题
C++基础知识练习(共30题)
包含选择题、判断题、填空题、简答题、编程题,并附参考答案与简要解析。
一、选择题(每题2分,共10分)
-
下列关于引用的说法正确的是:
A. 引用可以重新绑定到其他对象
B. 引用必须在定义时初始化
C. 引用可以为null
D. 引用大小不定
答案:B
解析:引用必须初始化且不可更改绑定对象。 -
下列哪个不是有效的C++标准类型?
A.
long long
B.
char16_t
C.
byte
D.
wchar_t
答案:C
解析 :byte
为C++17新增枚举类std::byte
,但不是关键字类型。 -
表达式
sizeof(int*)
的结果通常是:A. 4
B. 8
C. 1
D. 与平台相关
答案:D
解析:指针大小与平台和编译器有关。 -
下列容器中,不保证元素连续存储的是:
A.
std::vector
B.
std::deque
C.
std::string
D.
std::array
答案:B
解析 :deque
底层分块存储,不连续。 -
下列代码输出是什么?
cpp
int x = 1;
std::cout << ++x << x++;
A. 12
B. 22
C. 未定义行为
D. 11
答案:C
解析:同一表达式中多次修改并读取无序,导致未定义行为。
二、判断题(每题1分,共5分)
序号 | 题目 | 正误 |
---|---|---|
1 | C++中,virtual 关键字用于声明虚函数和实现多态。 |
✔ |
2 | 在栈上分配的对象需要手动调用delete 释放。 |
✘ |
3 | std::unique_ptr 可被复制赋值。 |
✘ |
4 | 函数模板可以重载普通函数。 | ✔ |
5 | auto 关键字可用于变量类型推断。 |
✔ |
解析:
- 正确;
- 栈上对象自动析构;
unique_ptr
不可拷贝;- 模板与函数重载可共存;
auto
启用编译器类型推断。
三、填空题(每题2分,共10分)
-
C++11新增的范围for循环语法为
______
。答案 :
for (auto& x : container)
-
std::vector
扩容时,通常是原容量的______
倍。答案:2
-
使用
new[]
分配的动态数组应使用______
释放。答案 :
delete[]
-
在类中,声明纯虚函数使用语法
______
。答案 :
virtual void func() = 0;
-
std::map
底层实现通常是红黑树,插入和查找平均时间复杂度为______
。答案:O(log n)
四、简答题(每题4分,共20分)
-
解释RAII的概念及其优点。
-
简述C++的三向绞接(Rule of Three/Five/Zero)。
-
比较
std::vector
与std::list
的使用场景和性能特点。 -
描述虚函数表(vtable)如何支持运行时多态。
-
简述C++对象的内存布局(对象头、成员变量、对齐)。
五、编程题(每题5分,共25分)
- 实现函数
countChars(const std::string& s)
,统计字符串中各字符出现次数,返回std::unordered_map<char, int>
。
cpp
std::unordered_map<char,int> countChars(const std::string& s) {
std::unordered_map<char,int> freq;
for (char c : s) freq[c]++;
return freq;
}
- 编写线程安全单例类
Singleton
,采用双重检查锁定。
cpp
class Singleton {
public:
static Singleton& getInstance() {
static std::mutex mtx;
if (!instance) {
std::lock_guard<std::mutex> lock(mtx);
if (!instance) instance = new Singleton();
}
return *instance;
}
private:
Singleton() {}
static Singleton* instance;
};
Singleton* Singleton::instance = nullptr;
- 写一个模板函数
swapElements
,交换任意容器中两元素。
cpp
template<typename C>
void swapElements(C& container, size_t i, size_t j) {
std::swap(container[i], container[j]);
}
- 实现一个简单的智能指针类
UniquePtr<T>
,支持析构时释放资源。
cpp
template<typename T>
class UniquePtr {
public:
explicit UniquePtr(T* ptr = nullptr) : ptr(ptr) {}
~UniquePtr() { delete ptr; }
T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }
// 禁止拷贝
UniquePtr(const UniquePtr&) = delete;
UniquePtr& operator=(const UniquePtr&) = delete;
private:
T* ptr;
};
- 实现函数
isPrime(int n)
,判断素数,返回bool
。
cpp
bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i*i <= n; ++i) {
if (n % i == 0) return false;
}
return true;
}