0

0

c++宏和const/enum/inline的对比 c++代码现代化技巧【必看】

冰火之心

冰火之心

发布时间:2026-01-04 18:32:03

|

763人浏览过

|

来源于php中文网

原创

应尽量避免宏,优先使用const、constexpr、enum class和inline变量:宏无类型、不参与检查;constexpr提供编译期求值与类型安全;enum class避免命名冲突;inline函数替代宏函数防展开错误;inline变量解决跨文件常量定义问题。

c++宏和const/enum/inline的对比 c++代码现代化技巧【必看】

宏(#define)在现代 C++ 中应尽量避免,优先使用 constconstexprenum classinline 变量——这不是教条,而是为了类型安全、调试友好、作用域可控和编译器优化更充分。

宏没有类型,而 const/constexpr 有完整类型信息

宏只是文本替换,不参与类型检查。比如:

#define MAX_SIZE 100
int arr[MAX_SIZE]; // OK
auto x = MAX_SIZE + 1.5; // 隐式转成 int,可能丢失精度,且编译器不警告

换成 constexpr 后,类型明确,还能参与模板推导:

constexpr int MAX_SIZE = 100;
auto x = MAX_SIZE + 1.5; // x 是 double,语义清晰,无隐式截断
  • const 适合运行期常量(如读配置后赋值)
  • constexpr 更推荐:编译期可求值,支持用在需要常量表达式的地方(数组大小、模板参数、switch 分支等)
  • 基本类型优先用 constexpr,避免裸 #define

枚举值用 enum class 替代宏定义的状态码

传统宏定义状态值易冲突、无命名空间、不可调试:

立即学习C++免费学习笔记(深入)”;

#define SUCCESS 0
#define ERROR_FILE 1
#define ERROR_NET 2
// 一不小心重定义或与其他头文件冲突

enum class 天然隔离作用域、有底层类型、支持强类型比较:

ChatMind
ChatMind

ChatMind是一款AI生成思维导图的效率工具,可以通过AI对话生成和编辑思维导图。

下载
enum class ResultCode : int {
    Success = 0,
    ErrorFile = 1,
    ErrorNet = 2
};
ResultCode r = ResultCode::Success; // 类型安全,IDE 可跳转、补全
  • 避免裸 enum(会隐式转为 int,失去类型保护)
  • 显式指定底层类型(如 : int)确保跨平台一致
  • 需要遍历或反射时,可用 magic_enum 等现代库辅助

内联函数比函数式宏更安全、更可调试

宏函数不求值参数、无作用域、容易因括号缺失出错:

#define SQUARE(x) x * x
int a = SQUARE(2 + 3); // 展开为 2 + 3 * 2 + 3 → 11,不是 25!

inline constexpr 函数替代,语义清晰、支持重载、能被调试器单步:

inline constexpr int square(int x) { return x * x; }
int a = square(2 + 3); // 正确计算为 25,且编译器大概率内联
  • 简单逻辑优先写 inline constexpr 函数(C++17 起无需手动加 inline,但显式写更清晰)
  • 模板函数天然内联,也适合泛型场景(如 square(x)
  • 宏函数仅在极少数需操作预处理器符号(如 __FILE__)时保留

全局常量用 inline 变量替代宏或 extern 声明

C++17 之前,跨文件共享常量常靠 extern const 声明 + 单独定义,繁琐易错;宏又没类型。现在直接用 inline constexpr 变量:

// config.h
inline constexpr double PI = 3.1415926535897932385;
inline constexpr std::string_view APP_NAME = "MyApp";

头文件中定义,多处包含不报 ODR 错误,类型安全,且所有编译单元看到同一地址(inline 保证)。

  • 适用于字面量、字符串视图、自定义字面量类型(需满足 literal type)
  • static const 更优:后者每个 TU 一份副本,inline 是真正“一个定义”
  • 类内静态常量也可用 inline static constexpr 直接定义

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1458

2023.10.24

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

107

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

321

2023.10.11

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

523

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

408

2024.03.13

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

162

2026.01.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 2.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1万人学习

Sass 教程
Sass 教程

共14课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号