c++指针常量,指向常量,指向常量的指针常量

指针

JAVA中,如果把一个引用修饰为final,那么这个引用只能指向这个对象,但是对象的内容还是可以被修改的
C++ 中,const修饰指针时,不仅可以修饰指针本身,还可以修饰指针所指向的内容
英文的说法为:const pointerpointer to const
这两种,各有两种写法:

  1. const pointer 指针常量
    int* const p;
    int *const p;
  2. pointer to const 指向常量的指针
    const int* p;
    int const *p;
  3. const pointer to const 指向常量的指针常量
    const int* const p;
    int const * const p;

阅读时

几种写法容易混淆,我的记忆方式:
const 右侧靠近原则const右侧的类型,决定了这个const修饰什么的目标。

  • 指针常量:
    首先是指针 int * p 在这之间插入const,const两侧分别是int * p
    由于这里const 右侧是p指针,那么这个const 修饰的就是指针本身。即为指针常量。
  • 指向常量:
    可以观察到,当忽略数据类型intconst的右侧是*p
    可以不恰当的理解为 *p为指针p的解引用,即为p指针指向的值
    故而,这里const 修饰的就是指向的值
  • 指向常量的指针常量
    依据上述,可推理。
    无论 const int* const p; 还是int const * const p;
    最左侧的const修饰的是值,另一个const修饰指针

记忆方式二const 右侧无* 修饰指针,const右侧有*修饰值

编写时

当我们想编写指向常量的指针常量,只要让两个const分布在*的两侧即可

代码示例

#include <iostream>
using namespace std;
class Person
{
public:
    Person(int a)
    {
        m_A = a;
    }
    int m_A;
};

指针常量

// 修饰指针
// p是一个指针常量,指针本身不可改变,指针指向的值可以改变
void constPointer()
{
    Person p1(10);
    cout << "p1.m_A = " << p1.m_A << endl;

    Person p2(20);
    cout << "p2.m_A = " << p2.m_A << endl;

    Person *const p = &p1;//这两种写法等价
    Person* const p = &p1;//这两种写法等价

    // p = &p2; //error 指针的指向不可改变
    p->m_A = 100; // 指针指向的内容可以改变
    cout << "p->m_A = " << p->m_A << endl;
}

指向常量

// 修饰值
// p是一个指向常量的指针,指针本身可以改变,指针指向的内容不可以改变
void pointerToConst()
{
    Person p1(10);
    cout << "p1.m_A = " << p1.m_A << endl;

    Person p2(20);
    cout << "p2.m_A = " << p2.m_A << endl;

    const Person *p = &p1;//这两种写法等价
    Person const *p = &p1;//这两种写法等价

    p = &p2; //指针的指向可以改变
    // p->m_A = 100; //error 指针指向的内容不可以改变
    cout << "p->m_A = " << p->m_A << endl;
}

指向常量的指针常量

// 修饰指针和值
// p是一个指向常量的指针常量,指针本身不可以改变,指针指向的内容也不可以改变
void constPointerToConst()
{
    Person p1(10);
    cout << "p1.m_A = " << p1.m_A << endl;

    Person p2(20);
    cout << "p2.m_A = " << p2.m_A << endl;

    const Person *const p = &p1;//这两种写法等价
    Person const *const p = &p1;//这两种写法等价

    // p = &p2; //error 指针的指向不可以改变
    // p->m_A = 100; //error 指针指向的内容不可以改变
    cout << "p->m_A = " << p->m_A << endl;
}

延申思考

引用

const 修饰引用:指向常量的引用(由于引用天生是指针常量,所以只有一种情况,也简称常量引用)
上述const右侧靠近原则同样适用
在写引用常量时,务必注意const 必须在& 左侧

const 右侧靠近原则 在引用中的分析

Person & const p = p1;无法通过编译,分析如下:
根据const右侧靠近原则 const 右侧是引用变量 p,而引用变量p本身即为常量。
这种写法,不仅语义上冗余,且法通过编译

Person const &p = p1;const Person &p = p1; 语法正确
同样根据const右侧靠近原则 const 的右侧为 & ,那么修饰的是指向的值。因此具有意义。

代码示例

void constReference()
{
    Person p1(10);
    cout << "p1.m_A = " << p1.m_A << endl;

    Person p2(20);
    cout << "p2.m_A = " << p2.m_A << endl;

    const Person &p = p1;//这两种写法等价
    Person const &p = p1;//这两种写法等价
    // Person & const p = p1;//error 引用本身不可以改变

    // p = p2; //error 引用本身不可以改变
    // p.m_A = 100; //error 引用指向的内容不可以改变
    cout << "p.m_A = " << p.m_A << endl;
}

参考

指针

引用
引用
引用内部原理

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值