
在 C++ 中,在成员函数声明后添加 const 关键字表示这是一个常量成员函数(const member function),这是 C++ 常量正确性的核心概念之一。
mutable)const 修饰的对象调用这些函数class MyClass {
public:
// 常量成员函数
void display() const;
// 非常量成员函数
void modify();
};当成员函数被声明为 const 时:
this 指针类型从 MyClass* 变为 const MyClass*const 指针访问// 编译器视角的转换
void display(const MyClass* this); // const 版本
void modify(MyClass* this); // 非 const 版本对象类型 | 常量成员函数 | 非常量成员函数 |
|---|---|---|
const 对象 | ✅ 允许 | ❌ 禁止 |
非 const 对象 | ✅ 允许 | ✅ 允许 |
class Counter {
int count; // 普通成员
mutable int accessCount; // mutable 成员
public:
void increment() const {
// count++; // 错误!不能修改普通成员
accessCount++; // 允许:mutable 成员可修改
}
};const 可参与函数重载,编译器根据对象的常量性选择版本:
class TextBuffer {
std::string text;
public:
// 非 const 版本
char& operator[](size_t pos) {
return text[pos]; // 返回可修改引用
}
// const 版本
const char& operator[](size_t pos) const {
return text[pos]; // 返回只读引用
}
};
// 使用场景
TextBuffer buffer;
buffer[0] = 'A'; // 调用非 const 版本
const TextBuffer cbuf;
char c = cbuf[0]; // 调用 const 版本
// cbuf[0] = 'B'; // 错误!尝试修改 const 对象class Person {
std::string name;
int age;
public:
// const Getter:安全访问成员
std::string getName() const { return name; }
int getAge() const { return age; }
};
void printPerson(const Person& p) {
// 可调用 const 方法
std::cout << p.getName() << ", " << p.getAge();
}class Shape {
public:
// 纯虚 const 方法:强制派生类实现常量计算
virtual double area() const = 0;
};
class Circle : public Shape {
double radius;
public:
double area() const override {
return 3.14159 * radius * radius;
}
};#include <vector>
void process(const std::vector<int>& vec) {
// 必须使用 const 版本的 begin/end
for (auto it = vec.begin(); it != vec.end(); ++it) {
// *it = 10; // 错误!迭代器是 const_iterator
}
}class DataWrapper {
std::vector<int> data;
public:
// 非 const 版本调用 const 版本避免重复
const int& at(size_t pos) const {
// 复杂边界检查...
return data[pos];
}
int& at(size_t pos) {
// 使用 const_cast 移除常量性
return const_cast<int&>(
static_cast<const DataWrapper*>(this)->at(pos)
);
}
};mutable 成员class Cache {
mutable std::mutex mtx; // 可被 const 方法修改
mutable std::vector<int> cachedData;
mutable bool cacheValid = false;
public:
void updateCache() const {
std::lock_guard<std::mutex> lock(mtx);
if (!cacheValid) {
// 模拟耗时计算
cachedData = {1, 2, 3, 4, 5};
cacheValid = true;
}
}
};class Matrix {
double* data;
int rows, cols;
public:
// const 方法返回 const 指针
const double* rowData(int r) const {
return data + r * cols;
}
// 非 const 方法返回普通指针
double* rowData(int r) {
return data + r * cols;
}
};最小权限原则:
constconst 正确性传播:
class A {
B* b;
public:
// 正确:返回 const 指针
const B* getB() const { return b; }
// 错误:返回非 const 指针
// B* getB() const { return b; }
};避免过度使用 mutable:
错误 1:修改成员变量
class Account {
double balance;
public:
void deductFee() const {
balance -= 5.0; // 错误!const 方法不能修改成员
}
};错误 2:调用非 const 方法
class Logger {
std::vector<std::string> logs;
public:
void addLog(const std::string& msg) { logs.push_back(msg); }
void printAll() const {
for (const auto& log : logs) {
std::cout << log << "\n";
}
addLog("Printed"); // 错误!const 方法调用非 const 方法
}
};错误 3:返回非 const 内部状态引用
class Config {
std::map<std::string, std::string> settings;
public:
// 危险:外部可通过引用修改内部状态
std::map<std::string, std::string>& getSettings() const {
return settings; // 错误!返回非 const 引用
}
};const 成员函数不会带来运行时性能开销:
关键总结:函数后的
const是 C++ 常量正确性的基石,它确保函数不修改对象状态,使 const 对象能安全调用方法,并通过重载提供更精确的接口设计。正确使用 const 成员函数能显著提高代码的健壮性和可维护性。