C++中指向const的指针能否指向非const类型变量?
指向const类型的指针的规则说明
const double *cptr 声明的指针完全可以指向非const的double类型变量,你给出的代码是符合C++语法规范的。
你可以把这类指针的约束理解为:指针自身承诺不会通过自己去修改指向位置的内容,而不是要求它指向的对象本身必须是常量。这个逻辑和你已经了解的const引用规则完全一致:const引用既能绑定const对象,也能绑定非const对象,核心都是「访问路径上的修改限制」,而非对目标对象本身的常量属性要求。
核心规则区分
很多人混淆const修饰指针的两种场景,你可以按const相对于*的位置来记:
- 当const在
*左侧:const T *p等价于T const *p,表示指向const T类型的指针- 限制:不能通过解引用
*p修改指向位置的值 - 无限制:指针变量
p本身存储的地址可以修改,可以重新指向其他T类型对象,不管目标对象本身是不是const
- 限制:不能通过解引用
- 当const在
*右侧:T * const p,表示指向T类型的const指针- 限制:指针变量
p本身存储的地址不能修改,初始化后不能再指向其他对象 - 无限制:如果指向的目标对象不是const,可以通过解引用
*p修改目标值
- 限制:指针变量
对你的代码的解释
你的示例代码可以正常编译运行,最终输出3.14:
#include<iostream> using namespace std; int main() { const double pi = 3.14; const double *cptr = π // 指向const类型的pi,符合约束:不会通过cptr修改pi的值 double dval = 3.14; cptr = &dval; // 指向非const类型的dval,依然符合约束:cptr只是承诺自己不修改dval,不要求dval本身不能修改 cout<<*cptr<<endl; }
这里唯一会触发编译错误的操作是试图通过cptr修改值,比如写*cptr = 2.718;,这违反了cptr自己的不修改承诺;但你直接通过变量名修改dval = 2.718;是完全合法的,毕竟dval本身没有被const修饰。
注意这个规则的反向是不成立的:你不能用普通的非const指针去指向const对象,比如
const double pi = 3.14; double *ptr = π会直接编译报错——因为普通指针意味着你可以通过它修改指向的值,这会破坏const对象的不可修改属性。
内容的提问来源于stack exchange,提问作者tall_call_9129
相关产品推荐
相关产品推荐

