Effective C++学习笔记之#define
前言
条款02:尽量以const、enum、inline替换#define;尽可能用编译器代替不必要的预处理器。
内容
一、对于单纯常量
1、const
有两种特殊的const,常量指针和class专属常量;
(1)常量指针
又分为常量指针、指针常量、指向常量的指针常量;
- const double *p;或者 double const *p;const读作常量,*读作指针,为常量指针;
本质是个指针,是指向一个常量的指针,也即指向的内容(*p)不可变。
- double * const p;*读作指针,const读作常量,为指针常量;
本质是个常量,是形容这个常量的类型是指针,也即指针指向不能改变。
- const double * const p;不管是指针的指向还是指针的指向内容都是常量,即是指向常量的指针常量。
实际栗子解释:
const double *p = &b 常量指针;不允许 *p = 6.66,因为常量指针的指向内容是常量不可变;但是允许 p = &c。
double * const p = &b 指针常量;不允许 p = &c,因为指针常量的指向是常量不可变;但是允许 *p = 6.66。
(2)Class的专属常量
class专属常量是指常量的作用域只在class里,需要在const的基础上再添加static关键字。
.h头文件里声明 static const double score;
.cpp实现文件里设初始值 const double Student::score = 66.6;
(很多编译器不支持在声明的时候设置初始值,只能将声明和设初值分开)
2、enum
如果遇到上述“不支持在声明的时候设置初始值”,就展现了enum的必要性。
eg:
class A { private: static const int LEN = 5; int score[LEN]; };
如果编译器(错误地)不允许static整数型class常量完成 in-class 初值设定,就应该用enum来代替:
class A { private: enum {LEN = 5}; int score[LEN]; };
二、对于形似函数的宏
将简单的函数写成宏,能免去函数调用的一些开销,但是使用不当会得到预料之外的结果。
有个经典的宏问题:
#define FINDMAX(a,b) ( (a) > (b) ? (a) : (b) ) FINDMAX(a++,b); //a被累加两次 FINDMAX(a++,b+10); //a被累加一次
用 inline 来代替此类宏的使用,既能免去函数调用的开销,也能避免一些不可预知的错误。
inline 将函数“内联” 起来了,在调用的时候是编译器使用相应的函数代码替换函数调用。编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了类似#define的隐患和局限性。
template <typename T> inline T FindMax(const T& a, const T& b) { return a>b?a:b; }
总结
1、对于单纯常量,尽量用const、enum替换#define;
2、对于形似函数的宏,最好用inline函数代替#define;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?