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 修饰符直接影响其可修改性。
系统当前共有 481 篇文章