Effective C++ 条款03:尽可能使用const
Effective C++ 条款03:尽可能使用const
核心思想:const
是 C++ 中强大的语义约束工具,能帮助编译器侦测错误、提高代码可读性、并支持编译器优化。
1. 定义常量
const int MAX_SIZE = 100; // 替换宏定义,类型安全
const std::string NAME = "Alice";
2. 修饰指针
-
指向常量的指针(底层
const
)const char* p = "Hello"; // 数据不可变 // p[0] = 'X'; // 错误:禁止修改 p = "World"; // 允许指向新地址
-
常量指针(顶层
const
)char greeting[] = "Hello"; char* const p = greeting; // 指针不可变 p[0] = 'X'; // 允许修改数据 // p = greeting + 1; // 错误:禁止修改指针
3. 修饰迭代器
std::vector<int> vec{1, 2, 3};
const std::vector<int>::iterator iter = vec.begin(); // 类似 T* const
*iter = 10; // 允许修改数据
// iter++; // 错误:迭代器不可移动std::vector<int>::const_iterator cIter = vec.cbegin(); // 类似 const T*
// *cIter = 20; // 错误:数据不可修改
cIter++; // 允许移动迭代器
4. 修饰函数参数与返回值
-
参数:避免意外修改
void print(const std::vector<int>& data) {// data.push_back(4); // 错误:const引用禁止修改for (auto num : data) std::cout << num << " "; }
-
返回值:防止误操作
const int getMagicNumber() { return 42; } // getMagicNumber() = 0; // 错误:返回值不可修改
5. const
成员函数
-
核心作用:
- 标记不修改对象状态的成员函数。
- 允许
const
对象调用。
-
示例:
class TextBlock {char* pText; public:// const版本:供const对象调用const char& operator[](size_t pos) const {return pText[pos]; // 返回const引用}// 非const版本:供普通对象调用char& operator[](size_t pos) {return pText[pos]; // 返回非const引用} };void demo() {const TextBlock ctb("World");TextBlock tb("Hello");tb[0] = 'h'; // 正确:调用非const版本// ctb[0] = 'w'; // 错误:调用const版本,返回值不可修改 }
6. mutable
突破 const
限制
class CachedData {
private:mutable int cache; // 允许const成员函数修改bool cacheValid = false;
public:int getValue() const {if (!cacheValid) {cache = compute(); // 允许修改mutable成员cacheValid = true;}return cache;}int compute() const { /* ... */ }
};
关键总结
- 声明常量时优先使用
const
而非#define
。 - 使用
const
指针/迭代器明确数据或指针的可变性。 - 函数参数传递时,对不改动的对象使用
const&
避免拷贝。 - 为不修改成员变量的函数添加
const
修饰符。 - 当成员变量需要在
const
函数中修改时,使用mutable
。
重要提醒:
const
成员函数的重载:根据调用对象的const
性自动选择版本。- 非
const
对象可调用const
成员函数(反之不成立)。