C++对象指针详解:常指针与指向常对象的指针区别
C++中的对象指针管理涉及两类常被混淆的概念:“指向对象的常指针”与“指向常对象的指针”。前者指针本身的地址固定不可变,后者指指针所指向的对象内容不可变。掌握两者的定义语法及 `const` 修饰位置,能有效防止误修改对象状态,提升程序的安全性。
指向对象的常指针(Pointer to Object, Constant Pointer)
指向对象的常指针是指将指针变量本身声明为 const 型。这意味着指针的值(即存储的地址)始终保持为其初值,初始化后不能再改变指向的其他对象,但其指向对象的内容可以被修改。
第1步:声明与初始化
定义形式为 类名 * const 指针变量名;。const 关键字位于指针变量名之前,明确表明该指针是常量。
// 假设 Time 是一个已定义的类
Time t1(10, 12, 15), t2;
Time * const ptr1 = &t1; // 必须在此处初始化,指定ptr1指向t1
// ptr1 = &t2; // 错误!编译报错:ptr1是常指针,不能改变指向
若先声明后赋值,则需在后续操作中固定其指向:
Time * const ptr1;
ptr1 = &t1; // 合法,首次赋值确定指向
ptr1 = &t2; // 错误,此后不能再改变指向
第2步:访问与修改对象属性
虽然指针 ptr1 本身不可变,但它所指向的对象 t1 依然是可变对象。因此,可以通过指针来修改对象的成员变量。
(*ptr1).hour = 18; // 合法,修改了t1的数据
ptr1 = &t2; // 非法,试图改变指针的指向
这种用法通常用于希望将一个指针变量固定地与一个对象相联系的场景,防止在复杂的函数调用或逻辑处理中发生误指向,增加安全性。
指向常对象的指针变量(Constant Pointer to Object)
此类指针用于保护它所指向的对象不被意外修改。指针变量可以重新指向其他对象,但任何试图通过该指针修改当前所指对象内容的行为都是非法的。
第1步:理解基本语法与约束
定义形式为 const 类名 * 指针变量名;。const 与类名相邻,表示指针指向的是常对象(或视为常量的普通对象)。
const Time *p; // p是指向常对象的指针
关键规则:如果一个对象已被声明为常对象,只能用指向常对象的指针去指向它,不能用一般的非 const 指针去指向它,否则类型不匹配。
第2步:指针的双重特性(指向常对象与非常对象)
指向常对象的指针具有灵活性:它可以指向常对象,也可以指向普通对象。但在两种情况下,都不能通过该指针修改对象的值。
- 指向常对象:合法且常见。
- 指向普通对象:指针可以获取普通对象的地址,但通过
*p进行的写操作将被编译器拦截。
Time t1(10, 12, 15); // 普通对象
const Time *p = &t1; // p指向普通对象t1,但视为只读
p->hour = 18; // 非法!不能通过const指针修改t1的值
t1.hour = 18; // 合法!直接通过对象名修改不受此限制
第3步:函数传参中的应用
当函数形参定义为指向常对象的指针时,目的是承诺在函数内部不会修改传入的对象。这使得实参既可以是常对象,也可以是普通对象。
// 正确:形参为指向常对象的指针,接受const或非const对象地址
void display(const Time *t) {
cout << t->getHour();
}
display(&t1); // t1是普通对象,合法
display(&const_t1); // const_t1是常对象,合法
// 错误:若形参是指向非const对象的指针,只能接受非const地址
void modify(Time *t);
modify(&const_t1); // 非法!试图用非const指针访问const数据
核心区别对比与注意事项
为了清晰区分两者,需严格关注 const 在声明语句中的位置及其对应的约束对象。
| 类型 | 代码示例 | 指针本身可变? | 指向对象可修改? | 主要用途 |
|---|---|---|---|---|
| 指向对象的常指针 (Const Pointer) |
Time * const p; |
否 (地址固定) | 是 | 固定绑定单一对象,防误换指针 |
| 指向常对象的指针 (Pointer to Const) |
const Time *p; |
是 (地址可变) | 否 (通过指针不可改) | 保护对象数据,常用于函数形参 |
第4步:易错点排查
- 混淆定义顺序:务必记住口诀:“
const在星号左边锁对象,在星号右边锁指针”。即const T *p锁对象(内容),T * const p锁指针(地址)。 - 混合使用场景:如果既有
const又有赋值运算符,如const int * const p;,则表示指针和所指对象都是常量,两者均不可变。 - 隐式转换:普通的非
const指针可以自动转换为const指针,反之则需显式强制类型转换(不安全,不建议)。
总结
正确使用 const 限定符修饰 C++ 对象指针,是构建健壮软件的基础。区分“常指针”与“指向常对象的指针”,关键在于判断你希望保护的是指针指向的记忆体地址,还是记忆体中的数据内容。在函数设计中,优先将参数定义为指向常对象的指针,既能兼容各类对象传参,又能提供编译期的数据保护机制。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













