文章目录
-
- [什么是 const 成员函数?](#什么是 const 成员函数?)
- [const 成员函数的核心作用](#const 成员函数的核心作用)
-
- [1. 承诺不修改对象状态](#1. 承诺不修改对象状态)
- [2. 允许常量对象调用](#2. 允许常量对象调用)
- [3. 基于 const 的重载](#3. 基于 const 的重载)
- [4. 与 mutable 成员的交互](#4. 与 mutable 成员的交互)
- [const 成员函数的优势](#const 成员函数的优势)
-
- [1. 增强代码安全性](#1. 增强代码安全性)
- [2. 明确表达设计意图](#2. 明确表达设计意图)
- [3. 支持常量对象](#3. 支持常量对象)
- [4. 促进良好的类设计](#4. 促进良好的类设计)
- 注意事项
- 总结表
什么是 const 成员函数?
在 C++ 中,在类的成员函数声明后面加上 const
关键字表示这是一个常量成员函数 。这种函数向编译器和使用者承诺:它不会修改调用它的对象的任何非静态成员变量(除非这些成员被声明为 mutable
)。
基本语法
cpp
class MyClass {
public:
// 常量成员函数
return_type functionName(parameters) const;
// 非常量成员函数
return_type functionName(parameters);
};
const 成员函数的核心作用
1. 承诺不修改对象状态
const 成员函数的主要作用是保证不会修改对象的内部状态(mutable 成员除外)。这既是一种承诺,也是一种约束,编译器会强制执行这一规则。
cpp
class BankAccount {
public:
double getBalance() const { // 常量成员函数
// balance = 1000; // 错误:不能在const成员函数中修改成员变量
return balance;
}
void deposit(double amount) { // 非常量成员函数
balance += amount; // 可以修改成员变量
}
private:
double balance;
mutable int accessCount; // 使用mutable修饰的成员
};
2. 允许常量对象调用
只有 const 成员函数才能被常量对象调用,这是 C++ 类型系统的重要安全特性。
cpp
void example() {
BankAccount regularAccount;
const BankAccount constAccount; // 常量对象
regularAccount.getBalance(); // 正确:非常量对象可以调用const成员函数
regularAccount.deposit(100); // 正确:非常量对象可以调用非const成员函数
constAccount.getBalance(); // 正确:常量对象可以调用const成员函数
constAccount.deposit(100); // 错误:常量对象不能调用非const成员函数
}
3. 基于 const 的重载
C++ 允许根据成员函数的 const 性进行重载,这为设计灵活的类接口提供了强大工具。
cpp
class StringCollection {
public:
// 非const版本:允许修改返回的字符串
std::string& getString(size_t index) {
return strings[index];
}
// const版本:返回常量引用,防止修改
const std::string& getString(size_t index) const {
return strings[index];
}
private:
std::vector<std::string> strings;
};
void example() {
StringCollection collection;
const StringCollection constCollection;
collection.getString(0) = "Modified"; // 调用非const版本,允许修改
std::string value = constCollection.getString(0); // 调用const版本,只允许读取
// constCollection.getString(0) = "Try"; // 错误:尝试修改常量对象
}
4. 与 mutable 成员的交互
mutable 关键字允许在 const 成员函数中修改特定成员变量,适用于需要记录内部状态但不影响逻辑常量的场景。
cpp
class DataCache {
public:
// 即使是在const成员函数中,也可以修改mutable成员
std::string getData(const std::string& key) const {
accessCount++; // mutable成员,可以修改
// 从缓存获取数据(假设这里是只读操作)
return cachedData.at(key);
}
int getAccessCount() const { return accessCount; }
private:
std::map<std::string, std::string> cachedData;
mutable int accessCount = 0; // 使用mutable修饰
};
const 成员函数的优势
1. 增强代码安全性
const 成员函数通过编译器强制检查,防止意外修改对象状态,减少潜在的 bug。
2. 明确表达设计意图
使用 const 成员函数明确告知代码使用者:这个函数只是查询对象状态,不会改变它。这使类接口更加清晰和自我文档化。
3. 支持常量对象
只有提供足够的 const 成员函数,类的常量对象才能真正有用,否则它们几乎无法进行任何操作。
4. 促进良好的类设计
设计类时考虑 const 成员函数,促使开发者思考哪些操作应该改变对象状态,哪些不应该,从而创建更清晰、更合理的类接口。
注意事项
-
默认使用 const:对于不修改对象状态的成员函数,应该将其声明为 const。
-
const 正确性:尽量使类具有 const 正确性,即提供足够的 const 成员函数以支持常量对象的使用。
-
避免滥用 mutable:mutable 应该谨慎使用,仅限于那些确实不影响对象逻辑状态的成员(如缓存、访问计数等)。
-
重载决策:理解 const 和非 const 版本成员函数的重载规则,确保调用正确的版本。
-
返回类型考虑:const 成员函数通常应该返回常量引用或值,而不是非常量引用,以保持 const 正确性。
总结表
情景 | 说明 |
---|---|
成员函数后加 const |
承诺不修改对象状态(mutable 成员除外) |
常量对象 | 只能调用 const 成员函数 |
非常量对象 | 可以调用 const 和非 const 成员函数 |
函数重载 | 可以根据 const 性提供不同版本的成员函数 |
mutable 成员 |
即使在 const 成员函数中也可以修改 |
基于学习笔记整理