C++ 进阶知识点整理

对 C++ 的中级核心知识点进行系统整理,这能帮助你突破基础层面,理解 C++ 的底层机制和工程化开发的关键技术,是从 "会用" 到 "用好" 的核心跨越。以下整理聚焦底层原理、工程化实践、现代 C++ 特性三大维度,兼顾深度和实用性。


一、C++ 内存模型与管理(中级核心)

1. 内存分区模型(底层核心)

表格

分区 存储内容 生命周期 特点
栈(Stack) 局部变量、函数参数、返回值 随作用域创建 / 销毁 自动管理,速度快,空间小(几 MB)
堆(Heap) new/malloc分配的内存 手动delete/free释放 手动管理,空间大(GB 级),易泄漏
全局 / 静态区 全局变量、static变量 程序启动到结束 整个程序生命周期唯一实例
常量区 字符串常量、const常量 程序启动到结束 只读,不可修改
代码区 编译后的二进制指令 程序启动到结束 只读,共享

关键考点

cpp

运行

复制代码
// 示例:内存分区验证
int global_var = 10; // 全局区
static int static_var = 20; // 静态区
const int const_var = 30; // 常量区

void test() {
    int local_var = 40; // 栈
    int* heap_var = new int(50); // 堆
    char* str = "hello"; // "hello"在常量区,str在栈
    delete heap_var; // 必须释放堆内存
}

2. 内存管理技术

(1)RAII(资源获取即初始化)
  • 核心思想:利用对象生命周期管理资源(内存、文件句柄、锁等),杜绝资源泄漏。
  • 典型应用:智能指针、自定义资源管理类。

cpp

运行

复制代码
// 自定义RAII类管理文件句柄
class FileGuard {
private:
    FILE* fp;
public:
    explicit FileGuard(const char* path, const char* mode) {
        fp = fopen(path, mode);
        if (!fp) throw runtime_error("文件打开失败");
    }
    ~FileGuard() { // 析构自动释放
        if (fp) fclose(fp);
    }
    // 禁用拷贝(避免double free)
    FileGuard(const FileGuard&) = delete;
    FileGuard& operator=(const FileGuard&) = delete;
    
    // 提供访问接口
    FILE* get() const { return fp; }
};

// 使用:无需手动close,出作用域自动释放
void useFile() {
    FileGuard fg("test.txt", "r");
    // 操作文件...
} // 析构自动fclose
(2)智能指针进阶

表格

类型 所有权 适用场景 注意事项
unique_ptr 独占所有权 单一所有者的资源 不可拷贝,可移动(std::move
shared_ptr 共享所有权 多对象共享资源 避免循环引用(配合weak_ptr
weak_ptr 弱引用 解决shared_ptr循环引用 lock()转为shared_ptr使用
auto_ptr 独占(已废弃) C++11 前,被unique_ptr替代 拷贝语义有问题,禁止使用

循环引用解决示例

cpp

运行

复制代码
#include <memory>
class B; // 前向声明

class A {
public:
    weak_ptr<B> b_ptr; // 用weak_ptr而非shared_ptr
    ~A() { cout << "A析构" << endl; }
};

class B {
public:
    shared_ptr<A> a_ptr;
    ~B() { cout << "B析构" << endl; }
};

void test() {
    shared_ptr<A> a = make_shared<A>();
    shared_ptr<B> b = make_shared<B>();
    a->b_ptr = b;
    b->a_ptr = a;
    // 无循环引用,析构正常执行
}
(3)内存池(高性能场景)
  • 核心思想 :预先分配一大块内存,按需分割使用,减少new/delete的系统调用开销。
  • 适用场景:高频创建 / 销毁小对象(如游戏、服务器开发)。

cpp

运行

复制代码
// 简易内存池示例
class MemoryPool {
private:
    char* pool; // 内存池起始地址
    size_t pool_size; // 总大小
    size_t used_size; // 已使用大小
public:
    MemoryPool(size_t size) : pool_size(size), used_size(0) {
        pool = new char[size]; // 预分配
    }
    ~MemoryPool() {
        delete[] pool;
    }
    
    // 分配内存
    void* allocate(size_t size) {
        if (used_size + size > pool_size) {
            throw bad_alloc();
        }
        void* ptr = pool + used_size;
        used_size += size;
        return ptr;
    }
    
    // 简化版:不实现free(实际需更复杂的空闲块管理)
    void deallocate(void* ptr) {}
};

// 使用
MemoryPool pool(1024 * 1024); // 1MB内存池
int* p1 = (int*)pool.allocate(sizeof(int));
char* p2 = (char*)pool.allocate(100);

二、面向对象进阶(OOP 深度)

1. 多态的底层实现

  • 虚函数表(vtable):每个含虚函数的类有一个虚函数表,存储虚函数地址;
  • 虚指针(vptr):每个对象包含一个指向虚函数表的指针(占用 8 字节内存);
  • 调用流程:通过 vptr 找到 vtable,再调用对应虚函数(运行时决议)。

关键结论

  • 虚函数会增加对象内存开销(1 个指针);
  • 纯虚函数(=0)使类成为抽象类,不能实例化;
  • final关键字禁止类继承 / 函数重写,override显式标记重写(编译器检查)。

2. 继承进阶

(1)虚继承(解决菱形继承二义性)

cpp

运行

复制代码
// 菱形继承问题:B、C都继承A,D继承B、C,A的成员会有两份
class A { public: int a; };
class B : virtual public A {}; // 虚继承
class C : virtual public A {}; // 虚继承
class D : public B, public C {};

// 使用:只有一份A的成员
D d;
d.a = 10; // 无歧义
(2)组合优于继承
  • 继承:"is-a" 关系,强耦合,子类依赖父类实现;
  • 组合:"has-a" 关系,弱耦合,通过包含对象实现功能复用。

cpp

运行

复制代码
// 组合示例(优于继承)
class Engine {
public:
    void start() { cout << "引擎启动" << endl; }
};

class Car {
private:
    Engine engine; // 组合Engine
public:
    void start() {
        engine.start(); // 复用Engine功能
        cout << "汽车启动" << endl;
    }
};

3. 模板编程(泛型编程)

(1)函数模板

cpp

运行

复制代码
// 通用交换函数
template <typename T>
void swap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

// 使用
int x=1, y=2;
swap(x, y); // 实例化为swap<int>
double a=3.14, b=5.67;
swap(a, b); // 实例化为swap<double>
(2)类模板

cpp

运行

复制代码
// 通用栈模板
template <typename T, size_t N>
class Stack {
private:
    T data[N];
    size_t top;
public:
    Stack() : top(0) {}
    void push(const T& val) {
        if (top < N) data[top++] = val;
    }
    T pop() {
        if (top > 0) return data[--top];
        throw runtime_error("栈空");
    }
};

// 使用
Stack<int, 10> int_stack; // int类型,容量10
Stack<string, 5> str_stack; // string类型,容量5
(3)模板特化(定制化实现)

cpp

运行

复制代码
// 通用模板
template <typename T>
class TypeTraits {
public:
    static const bool is_int = false;
};

// 特化:int类型
template <>
class TypeTraits<int> {
public:
    static const bool is_int = true;
};

// 使用
cout << TypeTraits<double>::is_int << endl; // 0
cout << TypeTraits<int>::is_int << endl;    // 1

三、现代 C++(C++11/14/17/20)核心特性

1. 移动语义与完美转发

(1)移动语义(&&右值引用)
  • 核心:转移资源所有权,避免深拷贝,提升性能。
  • 右值 :临时对象、字面量(如10"hello"),无名称,不能取地址。

cpp

运行

复制代码
class MyString {
private:
    char* data;
    size_t len;
public:
    // 构造函数
    MyString(const char* str) {
        len = strlen(str);
        data = new char[len+1];
        strcpy(data, str);
    }
    
    // 拷贝构造(深拷贝)
    MyString(const MyString& other) {
        len = other.len;
        data = new char[len+1];
        strcpy(data, other.data);
    }
    
    // 移动构造(浅拷贝,转移资源)
    MyString(MyString&& other) noexcept {
        len = other.len;
        data = other.data; // 转移指针
        other.data = nullptr; // 原对象置空,避免析构释放
        other.len = 0;
    }
    
    ~MyString() {
        if (data) delete[] data;
    }
};

// 使用:移动构造
MyString getString() {
    return MyString("test"); // 返回临时对象(右值)
}
MyString s = getString(); // 调用移动构造,无深拷贝
(2)完美转发(std::forward
  • 核心:保持参数的左值 / 右值属性,用于模板函数转发参数。

cpp

运行

复制代码
template <typename T>
void wrapper(T&& arg) {
    func(std::forward<T>(arg)); // 完美转发
}

void func(int& x) { cout << "左值引用" << endl; }
void func(int&& x) { cout << "右值引用" << endl; }

// 使用
int a = 10;
wrapper(a); // 左值,调用func(int&)
wrapper(20); // 右值,调用func(int&&)

2. 类型推导进阶

  • auto:推导变量类型(必须初始化);
  • decltype:推导表达式类型;
  • decltype(auto):结合 auto 和 decltype,推导返回值类型。

cpp

运行

复制代码
// decltype(auto)示例
int x = 10;
decltype(auto) y = x; // int(x是左值)
decltype(auto) z = (x); // int&((x)是左值表达式)

// 函数返回值推导
template <typename T, typename U>
decltype(auto) add(T&& a, U&& b) {
    return a + b;
}

3. 其他实用特性

表格

特性 作用 示例
constexpr 编译期计算 constexpr int square(int x) { return x*x; }
lambda表达式 匿名函数 auto f = [](int x) { return x*2; };
std::optional 处理可能为空的值 optional<int> getVal() { return 10; }
std::variant 类型安全的联合体 variant<int, string> v = "hello";
range-based for 简化容器遍历 for (auto& x : vec) { ... }

四、工程化与性能优化

1. 异常处理进阶

  • 异常规范noexcept标记函数不抛出异常(编译器优化);
  • 异常安全:保证异常抛出后,资源不泄漏、对象状态有效。

cpp

运行

复制代码
// 异常安全的函数
void safeFunc() noexcept {
    // 不会抛出异常的代码
}

// 异常捕获层级
try {
    // 可能抛异常的代码
    throw runtime_error("错误");
} catch (const runtime_error& e) {
    // 处理运行时异常
} catch (const exception& e) {
    // 处理所有标准异常
} catch (...) {
    // 处理未知异常
}

2. 性能优化原则

  1. 减少拷贝 :使用移动语义、const&传参;
  2. 避免虚函数调用:高频函数尽量不用虚函数(减少间接调用);
  3. 内存对齐alignas指定对齐方式,提升缓存命中率;
  4. 减少内存分配:使用内存池、复用对象;
  5. 编译器优化 :开启-O2/-O3(Release 模式)。

3. 代码规范与最佳实践

  1. 禁用裸指针:优先使用智能指针;
  2. 禁用NULL :使用nullptr
  3. 禁用goto:用循环 / 函数替代;
  4. 常量使用constexpr:编译期确定值;
  5. 避免全局变量:使用单例 / 局部静态变量。

总结

  1. 内存管理:核心是理解内存分区模型,掌握 RAII 思想,用智能指针替代裸指针,高性能场景可使用内存池;
  2. OOP 进阶:深入理解多态的虚函数表实现,优先使用组合而非继承,模板编程是泛型开发的核心;
  3. 现代 C++:移动语义、完美转发、类型推导是提升代码性能和简洁性的关键,需熟练掌握 C++11 及以上特性;
  4. 工程化:异常安全、性能优化、代码规范是中高级开发的必备能力,决定代码的稳定性和可维护性。

这些中高级知识点是 C++ 开发的核心壁垒,建议结合实际项目(如高性能服务器、游戏引擎、嵌入式开发)反复实践,才能真正理解和掌握

相关推荐
小猪咪piggy3 小时前
【Python】(4) 列表和元组
开发语言·python
Sayuanni%34 小时前
初阶_多线程1(线程含义与关键属性)
java
程序媛徐师姐4 小时前
Java基于微信小程序的模拟考试系统,附源码+文档说明
java·微信小程序·java模拟考试系统小程序·模拟考试微信小程序·模拟考试系统小程序·模拟考试小程序·java模拟考试小程序
難釋懷4 小时前
Lua脚本解决多条命令原子性问题
开发语言·lua
CoderCodingNo4 小时前
【GESP】C++ 二级真题解析,[2025年12月]第一题环保能量球
开发语言·c++·算法
疯狂敲代码的老刘4 小时前
JDK 1.6到25 全版本网盘合集 (Windows + Mac + Linux)
java·linux·windows·macos·jdk
夕除4 小时前
js--15
java·jvm·spring
独好紫罗兰4 小时前
对python的再认识-基于数据结构进行-a005-元组-CRUD
开发语言·数据结构·python
曾经的三心草4 小时前
redis-9-集群
java·redis·mybatis