引用不能绑定到"无物"?

引用不能绑定到"无物"?

在《深度探索C++对象模型》第3.4节中提到:

至于reference,则不需要针对可能的0值做防卫,因为reference不可能参考到“无物”(no object).

但实际上,因为referennce实际上是指针,可以设法将reference设为nullptr,如下:

#include <iostream>

void showAddr(int& ref) 
{
    // 打印ref引用得对象的地址
    std::cout << static_cast<void*>(&ref) << std::endl;
}

int main()
{
    showAddr(*static_cast<int*>(nullptr));
}

在g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0上编译输出如下:

0

在stckoverflow的一个帖子上也提到reference是可以绑定到nullptr的。

  1. A pointer can be assigned nullptr, whereas a reference must be bound to an existing object. If you try hard enough, you can bind a reference to nullptr, but this is undefined and will not behave consistently.

当然这权当玩笑之作,应该不会有人故意这么干。

引用和指针的区别

正好找到了上面的帖子,学习一下高赞评论总结的引用和指针的区别:

  1. 指针能重新赋值,但引用不能重新绑定,而且必须在初始化时就绑定;
int x = 5;
int *p;     // OK
p = &x;     // OK

// int &q;  // Error !
int &r = x  // OK
  1. 指针有自己的identity(我理解为指针是一种确切的类型),有确切的、可见的地址,这个地址能使用&(取址符)获得,能用sizeof操作符获取其确切的大小;但这些操作符作用于引用身上实际上是对其绑定的对象进行操作,引用的地址和大小也都是不可见的;

  2. 可以使用任意间接级别的指针(可以创建一个pointer,其指向的也是一个pointer,而且可以嵌套任意级别)。但引用只提供一个间接级别(没有引用的引用);

int x = 0;
int *p = &x;
int **pp = &p; // OK
  1. 一个指针可以被赋值为nullptr,但引用必须绑定到一个存在的对象上。当然,也可以把引用绑定到nullptr,但行为是未定义的;
  2. 指针能遍历一个数组,使用++操作符就能令指针指向下一个对象,使用+4就能指向第五个对象,无论指针指向什么对象;
  3. 指针使用*解引用来访问其指向的内存地址,引用可以直接使用。指针指向一个class/struct时,使用->来访问其成员(变量/函数),而引用使用.
  4. 引用不能放到数组中(没有引用的数组,但要注意有数组的引用),而指针可以;
int arr[] = {1,2,3,4,5};
// int& arrOfRef[2] = {arr[0], arr[1]}; // Error !
int (&refToArr)[5] = arr; // OK
  1. const引用可以绑定到临时对象上,但指针不行。
const int& x = int(12);  // OK
// int* y = &int(12);       // Error !
posted @ 2022-10-24 21:58  流云cpp  阅读(37)  评论(0)    收藏  举报