C++ 中 const
成员函数与 const
数据成员的限制对比及指针行为验证
一、const
成员函数与 const
数据成员的限制是否相同?
不完全相同,两者的限制机制和范围不同:
const
成员函数
• 限制:禁止修改类的非mutable
数据成员(通过隐式const this
指针实现)。• 允许:修改
mutable
修饰的成员变量。• 示例:
class Test { public: void modify() const { data = 10; // ❌ 编译错误:const 成员函数不能修改非 mutable 成员 mutableData = 20; // ✅ 允许修改 mutable 成员 } private: int data; mutable int mutableData = 0; };
const
数据成员
• 限制:无论是否在const
成员函数中,初始化后均不可修改。• 初始化方式:必须在构造函数初始化列表中赋值。
• 示例:
class Test { public: Test(int val) : constData(val) {} void modifyConst() { // constData = 20; // ❌ 编译错误:const 数据成员不可修改 } private: const int constData; };
结论:
• const
成员函数通过限制 this
指针的常量性,间接禁止修改普通成员。
• const
数据成员通过语法直接禁止修改,与函数是否为 const
无关。
二、普通指针成员在 const
成员函数中的限制
普通指针成员(非 const
指针)在 const
成员函数中:
• 指针本身(地址)可修改:允许重新赋值指针。
• 指针指向的内容不可修改:若指针类型为非常量指针(如 int*
),则通过指针修改内容会被禁止。
• 示例:
class Test { public: Test(int* p) : ptr(p) {} void modifyPtr() const { ptr = nullptr; // ✅ 允许:修改指针本身的值 *ptr = 10; // ❌ 错误:若 ptr 是 int*,则不允许修改指向的内容 } private: int* ptr; };
关键点:
• 若指针指向 const
数据(如 const int*
),则无论函数是否为 const
,均不能修改内容。
• 若指针本身是 const
(如 int* const
),则指针地址不可修改,但内容可修改(需非 const
数据)。
三、const
指针成员在普通成员函数中的限制const
指针成员(如 int* const
)在普通成员函数中:
• 指针本身(地址)不可修改:初始化后无法重新赋值。
• 指针指向的内容可修改:若指针指向非 const
数据,则允许修改内容。
• 示例:
class Test { public: Test(int val) : constPtr(new int(val)) {} ~Test() { delete constPtr; } void modifyContent() { *constPtr = 20; // ✅ 允许:修改指针指向的内容 // constPtr = nullptr; // ❌ 错误:指针本身不可修改 } private: int* const constPtr; // const 指针(地址不可变) };
关键点:
• const
指针的初始化必须在构造函数初始化列表中完成。
• 若指针指向 const
数据(如 const int* const
),则内容和地址均不可修改。
四、综合验证代码
#include <iostream> class Test { public: Test(int val) : constData(val), ptr(&val), constPtr(new int(val)) {} ~Test() { delete constPtr; } // const 成员函数 void constFunc() const { // constData = 10; // ❌ 错误:const 数据成员不可修改 // ptr = nullptr; // ✅ 允许:修改普通指针的地址 // *ptr = 20; // ❌ 错误:ptr 是 int*,指向内容不可修改 *constPtr = 30; // ✅ 允许:修改 const 指针指向的内容 } // 非 const 成员函数 void nonConstFunc() { constData = 10; // ❌ 错误:const 数据成员不可修改 ptr = nullptr; // ✅ 允许:修改普通指针的地址 // *constPtr = 40; // ❌ 错误:constPtr 是 int* const,指向内容可修改,但此处 constData 是 const } private: const int constData; // const 数据成员 int* ptr; // 普通指针成员 int* const constPtr; // const 指针成员 }; int main() { int value = 5; Test t(value); t.constFunc(); t.nonConstFunc(); return 0; }
编译结果:
• constFunc
中修改 constData
和 *ptr
会报错。
• nonConstFunc
中修改 constData
会报错,但修改 ptr
合法。
五、总结
场景 | 能否修改指针地址 | 能否修改指针指向的内容 | 原因 |
---|---|---|---|
const 成员函数 + 普通指针 | ✅ 可以 | ❌ 不可以(若非常量指针) | const 成员函数限制 this 指针的常量性,禁止修改成员变量(除非 mutable ) |
const 成员函数 + const 指针 | ❌ 不可以 | ❌ 不可以(若指向 const ) | 指针本身和内容均被 const 限制 |
普通成员函数 + const 指针 | ❌ 不可以 | ✅ 可以(若指向非常量) | const 指针的地址不可变,但内容可修改(除非数据本身是 const ) |
核心规则:
• const
成员函数通过 const this
限制成员变量修改。
• const
数据成员和指针的 const
修饰符直接影响其可修改性。
系统当前共有 449 篇文章