五、C++新特性、关键字与编译原理

五、C++新特性、关键字与编译原理(共25项)

1.C/C++中宏定义的相关知识

2.C/C++中typedef关键字的相关知识

3.介绍一下register关键字

4.介绍一下const关键字

5.介绍一下external关键字

6.介绍一下volatile关键字

7.介绍一下dynamic在什么时候使用

8.#include<file.h> 与 #include "file.h"的区别?

9.const和#define有什么区别?

10.介绍一下static关键字的作用

11.完成字符串拷贝可以使用 sprintf、strcpy及 memcpy函数,请问这些函数有什么区别。

12.C++11的新特性都有哪些?

13.sizeof与strlen的区别?

14.C++17/20/23中哪些特性在AI工程中高频使用?

15.STL容器在AI数据处理和推理服务中如何选择?

16.std::string_view、std::span、std::optional在高性能接口中有什么价值?

17.为什么RAII是C++资源管理的核心思想?

18.在C++程序中调用被C编译器编译后的函数,为什么要加extern "C"?

19.CMake、ABI兼容和依赖管理在AI SDK交付中为什么重要?

20.C++中异常处理机制

21.什么时候用static

22.头文件中的#ifndef/define/endif有什么作用?

23.内联函数在编译时是做参数类型检查?

24.C++移动语义和完美转发如何减少AI数据拷贝?

25.C++模板、CRTP和类型擦除如何用于高性能框架?

结论先行

这25项围绕三条主线:

  1. 关键字/预编译 :宏、conststaticexternvolatile 等控制编译与链接行为;
  2. C++现代特性 :C++11/17/20/23 的移动语义、智能指针、string_view/span/optional、模板/CRTP/类型擦除提升性能与类型安全;
  3. AI工程落地:RAII 管理资源、CMake/ABI 兼容保障 SDK 交付、移动语义减少张量/数据拷贝 ⚙️

一、预处理与关键字

1. 宏定义

文本替换,无类型检查。

复制代码
#define PI 3.14
#define MAX(a,b) ((a)>(b)?(a):(b))

缺点:无作用域、无类型安全、调试困难。现代 C++ 优先用 constinlineconstexprtemplate 替代。

2. typedef

给类型起别名。

复制代码
typedef unsigned int uint;
typedef std::vector<int> IntVec;

C++11 后更推荐 using

复制代码
using uint = unsigned int;
3. register

建议编译器把变量放入寄存器。

C++11 起已废弃,编译器优化通常比人工指定更好。

4. const

表示只读,编译期常量或运行期常量。

复制代码
const int a = 10;
void foo(const std::string& s);  // 避免拷贝

增强可读性、安全性,支持编译期优化。

5. extern

声明外部定义的全局变量/函数,用于跨文件共享。

复制代码
// a.cpp
int g_count = 0;
// b.cpp
extern int g_count;
6. volatile

告诉编译器不要优化该变量,每次从内存读取。

用于硬件寄存器、多线程中被其他线程修改的变量。

但不保证原子性和内存序,多线程同步请用 std::atomic

7. dynamic 什么时候使用?

应指 dynamic_cast:用于多态类型间安全向下转型。

复制代码
Base* p = new Derived();
Derived* d = dynamic_cast<Derived*>(p);  // 失败返回 nullptr

运行时检查,有开销,只用于含虚函数的类。

8. #include <file.h> vs #include "file.h"
  • < >:从系统/标准库路径查找;
  • " ":先从当前项目路径查找,再查系统路径。
9. const vs #define
const #define
有类型、作用域、可调试 文本替换,无类型
编译器可优化 预处理替换
现代 C++ 推荐 尽量少用
10. static 关键字作用

三种场景:

  1. 局部静态变量:延长生命周期至程序结束;
  2. 文件内静态变量/函数:限制链接域,仅当前文件可见;
  3. 类静态成员:类级别共享。
11. sprintf/strcpy/memcpy 区别
函数 功能 安全性
strcpy 字符串拷贝,遇 \0 停止 无边界检查,易溢出
memcpy 按字节拷贝固定长度 不处理重叠,需保证不越界
sprintf 格式化输出到字符串 无边界检查,极易溢出

现代 C++ 推荐 std::stringstd::snprintfstd::copy

13. sizeof vs strlen
  • sizeof:编译期运算符,返回类型/对象占用的字节数,含 \0

  • strlen:运行时函数,返回 C 字符串有效长度,不含 \0

    char s[] = "abc";
    sizeof(s); // 4
    strlen(s); // 3

18. 调用 C 编译后的函数为何要 extern "C"

C++ 编译器会对函数名做名字修饰(name mangling) ,C 编译器不会。

extern "C" 告诉 C++ 编译器按 C 规则链接,确保能找到 C 库中的符号。

复制代码
extern "C" {
    #include "c_lib.h"
}
21. 什么时候用 static
  • 需要限制全局变量/函数作用域到当前文件;
  • 函数内需要保持状态的变量;
  • 类成员需要类级共享。
22. 头文件 #ifndef/#define/#endif 作用

防止头文件被多次包含,避免重复定义。

现代也常用 #pragma once(更简洁,但非标准)。

23. 内联函数在编译时做参数类型检查?

是的。内联函数是真正的函数 ,编译器会做类型检查、作用域检查,并可能将函数体直接展开到调用处。

宏则只做文本替换,无类型检查。


二、C++ 新特性

12. C++11 新特性

核心亮点:

  • auto / decltype
  • 范围 for 循环
  • 右值引用与移动语义
  • std::unique_ptr / shared_ptr / weak_ptr
  • nullptr
  • constexpr
  • Lambda 表达式
  • 并发库(threadmutexfuture
  • 初始化列表、委托构造、默认/删除函数(= default / = delete
  • std::arraystd::tuplestd::unordered_map
14. C++17/20/23 在 AI 工程中的高频特性
标准 特性 AI 场景
C++17 std::string_view 避免字符串拷贝,模型配置名、算子名
C++17 std::optional 可选返回值,错误处理优雅
C++17 if constexpr 编译期分支,模板框架
C++17 结构化绑定 多返回值解包
C++20 std::span 张量切片、缓冲区视图
C++20 Concepts 模板约束,提升报错可读性
C++20 Modules 替代头文件,加速编译
C++20 Coroutines 异步推理、流式响应
C++23 std::expected 显式错误处理

三、AI 工程实践

15. STL 容器在 AI 数据处理和推理服务中如何选择
  • 连续内存 + 随机访问 → std::vector(张量数据、batch)
  • 频繁插入删除中间元素 → std::list(较少用)
  • 索引/缓存 → std::unordered_map
  • 有序配置/日志 → std::map
  • 避免拷贝的大缓冲区 → std::spanstd::string_view
16. string_view / span / optional 在高性能接口中的价值
  • string_view:只读字符串视图,零拷贝传参;
  • span:连续内存视图,安全替代裸指针+长度;
  • optional:显式表达"可能无值",替代魔术值或裸指针,降低空指针风险。
17. 为什么 RAII 是资源管理核心思想

RAII:资源获取即初始化。

对象构造时获取资源,析构时自动释放。

结合智能指针,能自动管理内存、文件、锁、网络句柄,避免泄漏和异常路径遗漏。

19. CMake、ABI 兼容和依赖管理在 AI SDK 交付中为什么重要
  • CMake:跨平台构建,统一编译规则;
  • ABI 兼容:编译器版本、标准库、编译选项不一致会导致链接/运行时崩溃,SDK 交付必须保证 ABI 一致;
  • 依赖管理:OpenCV、CUDA、ONNX Runtime 等依赖复杂,需明确版本和传递依赖,避免"在我机器上能跑"。
20. C++ 异常处理机制
复制代码
try {
    throw std::runtime_error("error");
} catch (const std::exception& e) {
    // 处理
}

异常会沿调用栈展开,自动调用局部对象的析构函数(栈展开)。

AI 服务中通常建议:核心推理路径少用异常,用 std::optional/std::expected/错误码保证性能可预测。

24. 移动语义和完美转发如何减少 AI 数据拷贝
  • 移动语义 :将资源所有权转移,而不是深拷贝。例如大 tensor 从预处理传到推理引擎时用 std::move
  • 完美转发std::forward 保持参数的左右值属性,避免临时对象不必要的拷贝。
    两者结合能显著降低大模型输入输出、中间特征图的内存拷贝开销 🚀
25. 模板、CRTP 和类型擦除如何用于高性能框架
  • 模板:编译期多态,零运行时开销,用于泛型算子、张量类型。
  • CRTP(奇异递归模板模式):静态多态,避免虚函数开销,实现编译期接口约束。
  • 类型擦除 :运行时统一接口,例如 std::functionany,用于插件系统中隐藏具体类型。

模板 + CRTP 适合热路径高性能;类型擦除适合需要运行时多态的插件边界。


整体联系

这25项勾勒出一条从源码编译现代 C++ 特性 再到AI 工程落地的链路:

宏/关键字/头文件

编译链接

C++11/17/20/23 新特性

RAII/智能指针/移动语义

高性能接口 string_view/span/optional

模板/CRTP/类型擦除框架设计

CMake/ABI/SKD 交付

掌握这些,才能写出既现代、又能在 AI 推理框架和 SDK 中稳定交付的 C++ 代码 💪

相关推荐
han_hanker1 小时前
新手公司项目实战
java·maven
vHelios1 小时前
【电商项目】商品搜索开发复盘(3):搜索与封装实现逻辑思考与编写
java
AI人工智能+电脑小能手1 小时前
大白话说Java设计模式-37-中介者模式(源码剖析篇)
java·设计模式·线程池·中介者模式·源码分析·executor·applicationeventmulticaster
焦虑的说说1 小时前
虚拟线程浅析
java
摇滚侠2 小时前
《SpringBoot 3:入门与应用实战》第 7 章 AOP 思想与实现 阅读笔记 13
java·spring boot·笔记
Mr. zhihao2 小时前
线上卡顿排查决策手册:场景 × 命令 × 现象 × 调整方案
java·开发语言·jvm
FYKJ_20102 小时前
springboot网上购书商城---附源码15749
java·spring boot·后端·python·spark·django·php
万法若空2 小时前
对数恒等式
人工智能·算法·机器学习