常量指针和引用的区别是什么?

52

常量指针和引用有什么区别?

常量指针不能再次绑定,与之类似的是引用。

我想知道在什么场景下会优先选择其中之一。它们在C++标准和实现方面有多大的差异?

谢谢。

5个回答

65

有三种类型的const指针:

//Data that p points to cannot be changed from p
const char* p = szBuffer;

//p cannot point to something different.  
char* const p = szBuffer;

//Both of the above restrictions apply on p
const char* const p = szBuffer;

上面的第二种方法最类似于引用。

引用和上述3种const指针之间存在重大差异:


3
参考(reference)是指向对象的别名(alias),这意味着可以在不解引用的情况下使用参考(请原谅这种令人困惑的术语)。 - Chinmay Kanchi
作为类成员的引用是否有地址? - Voyager

8

何时使用每个选项:

引用(reference):默认情况下使用。人们很容易对空指针进行解引用,使用引用可以避免这种风险。

常量指针(const pointer):当您想要引用但无法创建引用时使用。例如,您正在编写驱动程序,并且希望获得一个指向内存映射开头的指针。在这种情况下,引用没有那么多意义。此外,如果需要一组元素,则无法使用引用(但是具有引用成员的简单类数组可以)。

在下一个示例中,常量指针检查了引用无法检查的错误:

int addFour( int* register ){
  if(isNull(arg)){
    throw NullPointerException();
  }  

  // some stuff
  *register += 4;

  return register;
}

// This could be any function that does pointer math.
bool isNull(const int* ptr){
  return( NULL == ptr );
}

8

我假设你指的是一个常量指针 (例如 int* const ptr),而不是指向常量的指针 (例如 int const* ptr)。

  • 不初始化引用会导致编译错误(避免了未初始化指针的问题)
  • 指针也可以指向数组,或者它可以为NULL,而引用总是只引用一个对象。
  • 语法非常不同

1
你可以引用一个数组元素: int& intRef(intArray[2]);。指向数组的const指针指向数组元素的地址。我不确定你第二个要点中的数组部分有多重要。也许你的意思是可以在指针上使用[]运算符。 - thebretness

5
除了这个重要的问题之外,其他答案几乎都已经涵盖了: 指针可以进行算术运算,但引用不行。 例如:
int a[3] = {39, 18, 97};
int * const b = a;
int c = *(b+1);  // sets c = 18

1
@JackDeeth 但是指针算术有时候也可以很有用,我想。 - Gaurav Singh

0

一些不同之处:

const指针可以指向NULL。

const指针可以指向对象数组。

通过去除const属性,const指针可以再次绑定。


一个指针可以指向对象数组的第一个元素...你同样可以有一个数组指针类型,并且也可以引用这样的类型。 - Brian R. Bondy
常量转换应该极为罕见,有充分的理由和充分的文档支持。大量混合使用转换和正常功能通常是设计不良的症状。 - thebretness
强制转换常量并写入常量变量会导致分段错误,因此这绝对不是一个好主意。在许多系统上,常量存储在单独的只读内存区域中,或者它们的值可以直接由编译器替换到计算中,避免了读取操作。 - Tronic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接