乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • C++ 学习路径
  • 第1章 C++概述与开发环境

    • C++ 语言概述与编译模型
    • 第一个 C++ 程序与规范
    • 开发环境配置
    • 预处理指令详解
  • 第2章 基本语法与类型系统

    • 变量与基本类型
    • 类型转换
    • 枚举类型
    • 引用与指针
    • 数组与 stdarray
    • 字符串与原始字符串字面量
    • const 与 constexpr
    • nullptr 与空指针
    • 类型推导 auto 与 decltype
    • 基于范围的 for 循环
    • 值类别全面解析
    • char16_t 与 char32_t
    • static_assert 编译期断言
  • 第3章 函数与重载

    • 函数声明与定义
    • 函数重载
    • 默认参数与内联函数
    • Lambda 表达式
    • 函数对象与 stdfunction
    • 后置返回类型与 noexcept
  • 第4章 类与对象

    • 类的基本定义
    • 构造函数与析构函数
    • 拷贝控制
    • 移动构造函数与移动赋值
    • 列表初始化与类内初始化器
    • 静态成员与嵌套类
    • 友元
    • =default 与 =delete
  • 第5章 继承与多态

    • 继承基础
    • 虚函数与多态
    • 虚函数表与动态绑定原理
    • 虚析构函数
    • 抽象类与纯虚函数
    • 多重继承与虚继承
    • 继承构造函数
  • 第6章 运算符重载

    • 运算符重载基础
    • 算术与关系运算符重载
    • 赋值与移动运算符重载
    • 特殊运算符重载
  • 第7章 模板与泛型编程

    • 函数模板
    • 类模板
    • 模板特化与偏特化
    • 可变参数模板
    • 别名模板与模板模板参数
    • SFINAE 与类型萃取
    • 依赖名与 typename/template 关键字
  • 第8章 异常处理

    • 异常处理机制
    • noexcept 与异常安全
    • RAII 与异常安全实践
  • 第9章 内存管理与智能指针

    • 动态内存与内存分区
    • RAII 惯用法
    • unique_ptr
    • shared_ptr 与 weak_ptr
    • 内存管理最佳实践
  • 第10章 右值引用与移动语义

    • 右值引用与值类别深度解析
    • std::move 原理与使用
    • 完美转发与 std::forward
    • 移动语义性能对比与最佳实践
  • 第11章 STL容器

    • vector 深度剖析
    • deque 内部机制
    • list 与 forward_list
    • map 与 set 深度解析
    • unordered 容器与哈希原理
    • array 与 tuple
    • 容器适配器
    • 容器选择全景指南
  • 第12章 STL算法与迭代器

    • 迭代器体系全解
    • 非变异算法
    • 变异算法
    • 排序与二分算法
    • Lambda 与算法组合
    • std::random 随机数库
    • 自定义迭代器开发
  • 第13章 IO流与文件

    • 标准 IO 流
    • 格式化输出控制
    • 文件流操作
    • 字符串流
    • std::regex 正则表达式
  • 第14章 并发与多线程

    • thread 基础与线程管理
    • mutex 与 lock_guard
    • unique_lock 与 condition_variable
    • thread_local 线程局部存储
    • atomic 与内存序
    • future 与 async 异步编程
    • std::chrono 时间库
  • 第15章 现代C++新特性

    • 从 C++11 到 C++20 演进路线
    • C++14 关键新特性
    • C++17 关键新特性
    • C++20 核心特性速览
  • 第16章 面试考点与最佳实践

    • C++ 综合最佳实践清单
    • 高频面试题精讲
    • 多线程面试题与实战
    • 内存管理常见陷阱与排查
  • 附录

    • C++ 核心知识点
    • C++ 专业术语

C++ 综合最佳实践清单

定义与作用

本章将 Effective C++/Effective Modern C++ 的核心条款提炼为可操作的检查单,覆盖类型推导、智能指针、移动语义、lambda、并发等维度,辅以飞翔科技项目规范。

核心原理

最佳实践分类框架

完整示例

示例一:Effective Modern C++ 核心条款实战

场景说明:白歌制定飞翔科技 C++ 代码规范时的参考清单。

#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <functional>

// ============================================================
// 条款 1:理解模板类型推导
// ============================================================
template<typename T>
void deduceRef(T&& param) {
    // T&& 是万能引用(forwarding reference)
    std::cout << "  推导类型: " << typeid(T).name() << "\n";
}

// ============================================================
// 条款 5:优先使用 auto 而非显式类型
// ============================================================
void autoVsExplicit() {
    // ✅ 避免无意的类型不匹配
    std::vector<int> v{1, 2, 3};
    auto sz = v.size();         // size_t,与平台一致
    // unsigned sz = v.size();  // ❌ 32位平台可能溢出
}

// ============================================================
// 条款 9:优先使用别名声明而非 typedef
// ============================================================
template<typename T>
using UserList = std::vector<T>;  // ✅ 别名模板

// template<typename T>
// typedef std::vector<T> UserListOld;  // ❌ 编译错误

// ============================================================
// 条款 12:为意在覆盖的函数加上 override
// ============================================================
class Base {
public:
    virtual void process(int id) { /*...*/ }
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    void process(int id) override { /*...*/ }  // ✅ 编译期检查
    // void process(unsigned id) override;      // ❌ 编译错误,签名不匹配
};

// ============================================================
// 条款 17:理解特殊成员函数的生成规则
// ============================================================
class RuleOfFive {
public:
    RuleOfFive() = default;
    ~RuleOfFive() = default;

    RuleOfFive(const RuleOfFive&) = default;            // 拷贝构造
    RuleOfFive& operator=(const RuleOfFive&) = default; // 拷贝赋值
    RuleOfFive(RuleOfFive&&) noexcept = default;        // 移动构造
    RuleOfFive& operator=(RuleOfFive&&) noexcept = default; // 移动赋值
};

// ============================================================
// 条款 23:理解 std::move 和 std::forward
// ============================================================
template<typename T>
decltype(auto) forwardExample(T&& param) {
    // std::move:无条件转换到右值
    // std::forward:条件转换(仅当实参是右值)
    return std::forward<T>(param);  // ✅ 完美转发
}

// ============================================================
// 条款 30:熟悉完美转发失败的情况
// ============================================================
// 以下场景完美转发可能失败:
// 1. 花括号初始化器:f({1,2,3}) 无法推导
// 2. 0 或 NULL 作为空指针:会被推导为整数
// 3. 重载函数名和模板名:歧义
// 4. 位域:不能绑定到引用

// ============================================================
// 飞翔科技代码审查检查单 (Code Review Checklist)
// ============================================================
void codeReviewChecklist() {
    // ☐ 用 auto 替代冗长类型声明
    // ☐ 用 nullptr 替代 NULL/0
    // ☐ 用 enum class 替代裸 enum
    // ☐ 所有虚函数覆盖都加 override
    // ☐ 不可继承的类加 final
    // ☐ 不抛异常的函数标记 noexcept
    // ☐ 移动构造/赋值标记 noexcept
    // ☐ 优先 unique_ptr,需要共享才用 shared_ptr
    // ☐ 避免裸 new/delete
    // ☐ 用 {} 统一初始化语法
    // ☐ 用 constexpr 替代宏常量
    // ☐ 用 static_assert 做编译期检查
    // ☐ Lambda 捕获明确:避免 [=] 和 [&] 通配
    // ☐ 多线程用 task-based (async) 而非 thread-based
    // ☐ 数据成员在声明处初始化
    // ☐ 函数参数:只读用 const&,消耗用 &&
    // ☐ 用 std::string_view 替代 const std::string& (C++17)
    // ☐ 用 [[nodiscard]] 标记不应忽略返回值的函数
}

int main() {
    std::cout << "=== 飞翔科技 C++ 最佳实践 ===\n\n";

    // auto 类型推导
    const int x = 42;
    auto a = x;          // int(const 被去掉)
    auto& b = x;         // const int&
    decltype(auto) c = x; // const int(保留 const)

    std::cout << "auto a = const int: " << typeid(a).name() << "\n";
    std::cout << "auto& b = const int: " << typeid(b).name() << "\n";

    // nullptr
    int* p = nullptr;  // ✅ 类型安全
    // int n = NULL;   // ❌ 歧义:是 0 还是空指针?

    // enum class
    enum class Status { OK, WARN, ERROR };
    Status s = Status::OK;
    // int x = Status::OK;  // ❌ 不隐式转换
    int y = static_cast<int>(Status::OK);  // ✅ 显式转换

    std::cout << "\nStatus::OK = " << static_cast<int>(s) << "\n";

    // [[nodiscard]] (C++17)
    auto getConfig = []() [[nodiscard]] -> int { return 42; };
    auto val = getConfig();  // ✅ 使用返回值
    // getConfig();          // ⚠️ 编译器警告:忽略返回值

    // 用 {} 初始化防止窄化
    int arr[] = {1, 2, 3};           // ✅
    // int n{3.14};                   // ❌ 窄化错误
    double d{42};                    // ✅ 加宽安全

    std::cout << "\n所有检查项通过\n";
}

示例二:项目代码规范检查单

飞翔科技 C++ 项目规范:

// ============================================================
// 命名规范
// ============================================================
class UserService           {};  // 类名:PascalCase
struct Point3D             {};  // 结构体:PascalCase
enum class ColorCode       {};  // 枚举:PascalCase

void processUserRequest();       // 函数:camelCase
int  user_id_;                   // 成员变量:snake_case_
const int kMaxConnections = 100; // 常量:k + PascalCase

// ============================================================
// 头文件规范
// ============================================================
// ✅ 使用 #pragma once
#pragma once

// ✅ 包含顺序:相关头文件 → 标准库 → 第三方 → 项目内
// #include "user_service.h"
// #include <string>
// #include <vector>

// ============================================================
// 异常安全保证
// ============================================================
template<typename T>
class SafeResource {
public:
    explicit SafeResource(T* ptr) : ptr_(ptr) {}
    ~SafeResource() { delete ptr_; }

    SafeResource(const SafeResource&) = delete;
    SafeResource& operator=(const SafeResource&) = delete;
    SafeResource(SafeResource&& other) noexcept
        : ptr_(other.ptr_) {
        other.ptr_ = nullptr;
    }

private:
    T* ptr_;
};

综合最佳实践速查表

语言用法

旧习惯现代替代标准
#define MAX 100constexpr int kMax = 100;C++11
NULL / 0nullptrC++11
enum Color {RED};enum class Color {Red};C++11
typedef vector<int> Vec;using Vec = vector<int>;C++11
for (it = v.begin(); ...)for (const auto& x : v)C++11
new / deletemake_unique / make_sharedC++11/14
auto_ptrunique_ptrC++11
throw()noexceptC++11
动态异常规范noexceptC++11
函数对象lambdaC++11
std::bindlambdaC++11
std::function f = add;auto f = add;C++11
ostringstreamstd::formatC++20
SFINAEConceptsC++20

设计原则

原则说明
RAII构造获取资源,析构释放资源
Rule of Five自定义任一特殊成员函数则全部定义
最少特权成员函数尽量 const,数据尽量 private
接口而非继承优先组合而非继承
值语义优先于引用语义
不可变优先默认 const
编译期检查static_assert、constexpr 优于运行时
类型安全避免 void*、C 风格转型

易错场景与面试考点

易错场景

1. 用 auto 推导 initializer_list

auto x = {1, 2, 3};     // x 是 std::initializer_list<int>
auto y{1};               // C++17: y 是 int
// 避免:用 auto 配合大括号时注意推导规则差异

2. 忽略 auto 的引用剥离

const auto& result = getHeavyObject();  // ✅ 避免拷贝
auto result = getHeavyObject();         // ❌ 可能触发拷贝

3. 模板中 = default 的含义

template<typename T>
class Wrapper {
    Wrapper(const Wrapper&) = default;  // 在模板中等同于 = delete?
    // 正确做法:显式用 SFINAE 或 requires
};

面试考点

考点要点
Effective C++ 核心RAII、const 正确性、避免默认生成的函数
Effective Modern C++型别推导、auto、智能指针、移动语义、lambda
代码审查项nullptr、override、enum class、{} 初始化
性能陷阱不必要的拷贝、错误的移动、锁粒度过大
安全陷阱裸指针、C 风格转型、未初始化变量
可维护性const 正确性、命名一致、RAII、明确所有权
下一页
高频面试题精讲