函数后的 `const` 关键字
函数后的 const
关键字
1. 含义与作用
成员函数(或运算符)参数列表后的 const
关键字表明:这是一个“常量成员函数”。
它向编译器做出承诺:这个函数不会修改其所属对象的任何非静态成员变量(mutable 修饰的变量除外)。
2. 为什么需要它?
- 设计意图与安全性:它明确了函数的职责。如果一个函数在逻辑上不应该修改对象状态(比如
getter
方法、计算并返回结果的函数),就应该声明为const
。这防止了你在函数内部无意中修改成员变量,编译器会阻止这种行为。 - 使对象能被常量对象调用:这是最关键的作用。一个被声明为
const
的对象(或对象的常量引用/指针),只能调用其类的const
成员函数。
示例:
class MyString {
private:char* m_data;int m_length;
public:// const 成员函数:承诺不修改对象状态int length() const { // 这是一个 getter,不会修改成员变量// m_length = 10; // 错误!编译器会报错,不能在 const 函数内修改成员return m_length;}// 非 const 成员函数:允许修改对象状态void clear() { // 这个函数需要修改对象,所以不能是 const 的// ... 清理 m_data 的操作m_length = 0; // 这是允许的}
};int main() {MyString s1;const MyString s2; // 常量对象std::cout << s1.length(); // 正确:非const对象可以调用const函数std::cout << s2.length(); // 正确:const对象可以调用const函数s1.clear(); // 正确:非const对象可以调用非const函数// s2.clear(); // 错误!编译失败:const对象不能调用非const成员函数//(因为clear()可能修改s2的状态,这违反了s2的常量性)return 0;
}
3. 重写与 const
的关系
在重写虚函数时,函数签名必须完全一致。这包括 const
属性。如果基类中的虚函数是 const
的,那么派生类中重写的函数也必须是 const
的(反之亦然),否则加上 override
会导致编译错误,因为它们被认为是两个不同的函数。
class Base {
public:virtual void print() const { // const 成员函数std::cout << "Base";}
};class Derived : public Base {
public:void print() const override { // 正确:签名一致,都是 conststd::cout << "Derived";}// void print() override { // 错误!缺少 const,不是有效的重写// std::cout << "Derived";// }
};
4. 总结 - 函数后的 const
- 目的:保证函数不修改对象状态,并允许常量对象调用该函数。
- 用法:放在成员函数的参数列表之后。
- 最佳实践:如果一个成员函数确实不需要修改任何成员变量,就一定要将其声明为
const
。这是设计良好类接口的重要原则。