指针
JAVA中,如果把一个引用修饰为final
,那么这个引用只能指向这个对象,但是对象的内容还是可以被修改的
C++ 中,const
修饰指针时,不仅可以修饰指针本身,还可以修饰指针所指向的内容
英文的说法为:const pointer 和 pointer to const
这两种,各有两种写法:
- const pointer 指针常量
int* const p;
int *const p;
- pointer to const 指向常量的指针
const int* p;
int const *p;
- const pointer to const 指向常量的指针常量
const int* const p;
int const * const p;
阅读时
几种写法容易混淆,我的记忆方式:
const 右侧靠近原则 : const
右侧的类型,决定了这个const
修饰什么的目标。
- 指针常量:
首先是指针int * p
在这之间插入const
,const
两侧分别是int *
和p
由于这里const
右侧是p
指针,那么这个const
修饰的就是指针本身。即为指针常量。 - 指向常量:
可以观察到,当忽略数据类型int
,const
的右侧是*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;
}