Const与&与*的花样组合


浅谈指针和引用


1. 指针

The C++ Programming Language 中,Bjarne说过:一个声明是自右向左的

char* const p;    // p is a const pointer to char
const char* p;    // p is a pointer to const char
char const * p;    // p is a pointer to const char

对于第三条语句,因为const要去结合类型,即结合char为const char, 所以和第二个是相同的定义类型。
[ 因为单独的一个 * 不属于类型, 即不存在单独的 const* ]
{ 如果让我们再回头看第一条语句,其实就是 const 结合了一个类型 char* }

2. 引用

如果你不清楚引用对象是什么类型的,就(假设可以这样理解)先去掉 '&' 符号,剩下的就是引用对象的类型

比如: const int & 是在引用const int类型的变量。

​ const int* & 是在引用const int*类型的变量。

​ 那么int * const& 是在引用什么呢?

对于int* const &来说,如果按上面的思路,似乎是在引用 指向int的常指针。
但引用一个常量,是没有意义的。
所以,该引用应该被理解为常引用
当A常引用B时,只能通过A使用B的值,不能通过A修改B。而A仍随B的变化而变化。

再看下面的例子,进一步理解”常引用“。

/* 定义 */
int a = 10;
int b = 20;

const int& A = a;  // 不能引用常量,所以是常引用
int& B = b;    // 普通引用

/* 赋值 */
a = 30;
cout << A;    // OutPut: 30
A = B;    // Fail
B = A;    // Success
(int&)A = B;    //Success( a = B )

三者的交叉使用


接着,让我们看三个例子,来具体地理解一下。

首先,对所有例子都有:
char c = '0';

例1

/* 定义 */
char* p1 = &c;

/* 传递 */
const char*& p2 = p1;    // Fail

结果:传递失败。
报错原因:p1指向char,p2却想引用指向const char的指针p1。
无法将参数从” char* “转化为” const char *& “。

例2

/* 定义 */
const char* p1 = &c;

/* 传递 */
const char*& p2 = p1;    // Success

/* 赋值 */
*p2 = '1';    // Fail
p2 = NULL;    // Success

结果:成功传递,且两次赋值分别成功、失败。
即p2是普通引用(引用对象是:指向const char的普通指针 )

例3

/* 定义 */
char* p1 = &c;

/* 传递 */
char* const & p2 = p1;    // Success

/* 赋值 */
*p2 = '1';    // Success
p2 = NULL;    // Fail
*p1 = '1';    // Success
p1 = NULL;    // Success

结果:成功传递,且两次赋值分别失败、成功。
即p2是常引用(引用对象是:指向char的指针 )

<常引用>的常见用途


最常见的用途是:使用引用传递参数时,如果不想改变引用对象的值,则需使用常引用。

  • 如果不用引用,对于结构类型的参数传递效率可能会很低。

  • 如果不用 const,则原对象可能会修改。

    尤其注意——指针的常引用容易写错。

    比如:

    const char* & A = B; // 不是常引用
    char* const & A = B; // 是常引用

结语


今天下午,突然想整理一下const 、’*’ 、 ‘&’ 之间的关系。

通过自己的不断测试,便有了如上浅见,希望能帮助到有需要的人。


  目录