目录
条款2:尽量以const、enum、inline替换#define
[1. 使用const替换常量宏](#1. 使用const替换常量宏)
[2. 类内的静态常量整型](#2. 类内的静态常量整型)
[3. 使用inline替换宏函数](#3. 使用inline替换宏函数)
条款1:视C++为一个语言联邦
C++是一个由多个次语言组成的整体,主要包括:
-
C语言部分:数组、指针、预处理等
-
面向对象编程:类、继承、虚函数等
-
模板编程:泛型编程
-
STL:容器、迭代器、算法等
当在这些次语言间切换时,高效编程的要求可能会改变。
示例对比
C风格函数:传值开销小
cpp
void fun2(int a) // 复制int的开销忽略不计
{
}
C++类对象:传引用更高效
cpp
class Student
{
private:
string name = "张三";
string gender = "男";
int id = 0;
};
void func(Student& s) // 传引用避免拷贝开销
{
}
每个次语言都有自己的规约,理解这一点有助于编写更高效的C++代码。
条款2:尽量以const、enum、inline替换#define
#define的常见用法
- 定义常量
#define NUM 5
- 定义宏函数
#define MAXNUM(A,B) ((A)>(B)?(A):(B))
#define的问题
-
宏会直接文本替换,编译错误信息难以理解
-
宏函数容易产生意外的副作用
-
无脑展开可能导致代码膨胀
解决方案
1. 使用const替换常量宏
const int num = 5;
特殊情况:常量字符串
const char* const str = "hello"; // 指针和内容都不可修改
2. 类内的静态常量整型
常规写法:
class C
{
private:
static const int _a = 1; // 现代编译器支持
public:
int a[_a];
};
对于老旧编译器,使用enum hack:
class C
{
private:
enum { _a = 5 }; // 使用匿名枚举替代
public:
int a[_a]; // 可以正常使用
};
优点:enum hack不能取地址,更安全。
3. 使用inline替换宏函数
有问题的宏函数:
#define MAXNUM(A,B) ((A)>(B)?(A):(B))
问题示例:
int a = 1, b = 2;
MAXNUM(++a, b); // a可能被多次递增
MAXNUM(++a, b+5); // 更复杂的副作用
改为inline函数:
inline int maxnum(int a, int b)
{
return a > b ? a : b;
}
或使用模板:
template<typename T>
inline T maxnum(const T& a, const T& b)
{
return a > b ? a : b;
}
总结
使用const、enum、inline替代#define的优势:
-
更好的类型检查:编译器能进行类型检查
-
更清晰的错误信息:调试更容易
-
避免副作用:inline函数参数只计算一次
-
作用域控制:const和enum有明确的作用域
-
更好的调试体验:调试器能看到符号名
遵循这些准则能让你的C++代码更安全、更易于维护。