C++ const成员函数什么意思 C++类中const修饰符作用详解【封装】

12次阅读

const 成员函数承诺不修改对象状态,仅允许访问 mutable 成员;const 成员变量须在初始化列表中赋值;const 参数影响绑定规则;const_cast 滥用易致未定义行为;const 性在继承中不可取消。

C++ const 成员函数什么意思 C++ 类中 const 修饰符作用详解【封装】

const 成员函数表示“不修改对象状态”

它告诉编译器和调用者:这个函数不会改变 this 指向的对象的任何非 mutable 成员。编译器会检查函数体内是否对非 mutable 成员赋值、调用非 const 成员函数,一旦违反就报错,比如:error: assignment of member 'x' in read-only object

常见误操作包括在 const 成员函数里调用 set_value()、给 count++、或返回 data_ 的非常量引用。这些都会触发编译失败。

  • 只有 const 成员函数能被 const 对象调用(例如 const MyClass obj; obj.get_x();
  • const 成员函数可以访问 mutable 成员(如缓存、计数器),这是唯一允许修改的例外
  • 重载时,const 和非 const 版本可共存,编译器按对象是否为 const 自动选择(如 operator[] 的两种实现)

const 修饰类成员变量 = 编译期只读初始化

声明为 const 的成员变量(如 const int id_;)必须在构造函数的 member initializer list 中初始化,不能在构造函数体里赋值。否则编译报错:error: uninitialized const member

它不是运行时保护,而是强制约束:没有默认值、不可被修改、不可被赋值,连移动 / 拷贝构造函数也不能绕过该限制。

立即学习C++ 免费学习笔记(深入)”;

  • 不能写 id_ = 42; 在构造函数内部 —— 必须写成 MyClass(int x) : id_(x) {}
  • 不能用 std::movestd::swap 修改它,哪怕通过 const_cast 强转也属于未定义行为
  • 若类型是自定义类,其默认构造函数不会被调用;必须显式初始化,且该类型需支持 const 构造

const 修饰成员函数参数影响重载与 隐式转换

参数加 const(如 void foo(const std::string& s))本身不构成重载区分依据,但结合引用类型和顶层 const,会影响绑定规则和函数匹配优先级。

真正关键的是:当参数是 const T& 时,它能接受临时对象、字面量、const 变量;而 T& 只能绑定非常量左值。这点在设计接口时直接影响可用性。

  • void set_name(std::string&&)void set_name(const std::string&) 可实现移动 + 拷贝双路径
  • 传入字符串字面量 "abc" 时,只能匹配 const char*const std::string&,不能匹配 std::string&
  • 避免把参数写成 const std::string(值传递 +const)—— 多一次无谓拷贝,且 const 在值参上无实际意义

const_cast 不是用来“去掉 const”的 工具

const 成员函数中用 const_cast 强转 this 指针去修改成员,仅在目标原本就非 const 时合法(例如外部对象是 MyClass obj;,内部调用 const_cast(this)->x_ = 1;)。如果对象本身是 const(如 const MyClass obj;),这么做就是未定义行为。

实际工程中,99% 的 const_cast 都是设计缺陷的信号:要么该成员应声明为 mutable,要么不该在 const 函数里改它,要么接口不该标记为 const

  • mutable 是唯一被标准认可的、在 const 成员函数中修改数据的合法方式
  • const_cast 绕过 const 约束,往往意味着封装边界被破坏,后续维护容易出隐蔽 bug
  • 第三方库接口返回 const T* 时,若你确定底层可写且需修改,应先确认文档是否允许,而不是直接强转
const 的真正价值不在语法层面,而在表达意图和约束调用契约。最容易被忽略的一点是:const 成员函数的 const 性无法被子类取消 —— 即使派生类重写了该函数,也必须保持 const 属性一致,否则不是重写而是重载,这会悄悄破坏多态预期。

text=ZqhQzanResources