关于引用不能为空的问题

强迫症专用头像 2011-07-22 09:40:41
引用与指针最主要的三个区别:
1、引用必须初始化
2、引用不能为空
3、引用指向一个变量后,他指向的对象不会再发生改变

举例如下:
1
int& a;//错误,必须初始化
int n;
int& b = n;//正确

2
char* p = NULL;
char& q = *p;//错误,引用不能为空

3
int a;
int b;
int& m = a;
m = b;//此时m仍然指向a,m = b相当于a = b,a的值被修改

1、3两点能够理解,但是关于第二点,因为p为NULL,所以取值*p会有问题,感觉这是指针的特性,不是引用的特性啊,更神奇的是char* p = NULL;char& q = *p;这两句在vs2005下编译运行都能通过,char* p = NULL;char& q = *p;char r = *p;这三句在vs2005下能编译通过,运行时在char r = *p处崩溃。给我的感觉是引用能够为空,牛人来解释下?
...全文
1236 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sdupoplar 的回复:]
引用其实在汇编层就是一个指针,直接用和作为函数参数都是如此,但是指针以后可以改值,引用改不了,引用为空了后,使用的话,和使用空指针一样。我反汇编了下,VC6下,release版优化了,不好看,debug版汇编代码如下:
C源码如下:

C/C++ code

#include <stdio.h>

int main()
{
char* p = NULL;
……
[/Quote]
你的例子相当好啊,精彩之极,追加一些分数给你吧。
总结引用与指针区别如下:
1、引用必须初始化
2、不能引用空指针指向的值//可以引用空指针,但是请慎用,详见10楼
3、引用总是指向在初始化时被指定的对象

结贴
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yucarl 的回复:]
编译时能通过 不代表运行时不崩溃!
[/Quote]
兄弟要认证看帖啊
CrySleeper 2011-07-22
  • 打赏
  • 举报
回复


[Quote=引用 3 楼 pengzhixi 的回复:]

标准说这样做的行为未定义
甚至 char*p=NULL; char*&ref=p;都是不好的代码。
[/Quote]
这个代码哪里不好?
sdupoplar 2011-07-22
  • 打赏
  • 举报
回复
引用其实在汇编层就是一个指针,直接用和作为函数参数都是如此,但是指针以后可以改值,引用改不了,引用为空了后,使用的话,和使用空指针一样。我反汇编了下,VC6下,release版优化了,不好看,debug版汇编代码如下:
C源码如下:

#include <stdio.h>

int main()
{
char* p = NULL;
char& q = *p;

p = new char;
*p = 'c';

printf("%c\n", q);


//char r = *p;

return 0;
}


对应汇编如下:

_TEXT SEGMENT
_p$ = -4
_q$ = -8
$T587 = -12
_main PROC NEAR ; COMDAT

; 4 : {

push ebp
mov ebp, esp
sub esp, 76 ; 0000004cH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-76]
mov ecx, 19 ; 00000013H
mov eax, -858993460 ; ccccccccH
rep stosd

; 5 : char* p = NULL;

mov DWORD PTR _p$[ebp], 0

; 6 : char& q = *p;

mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR _q$[ebp], eax

; 7 :
; 8 : p = new char;

push 1
call ??2@YAPAXI@Z ; operator new
add esp, 4
mov DWORD PTR $T587[ebp], eax
mov ecx, DWORD PTR $T587[ebp]
mov DWORD PTR _p$[ebp], ecx

; 9 : *p = 'c';

mov edx, DWORD PTR _p$[ebp]
mov BYTE PTR [edx], 99 ; 00000063H

; 10 :
; 11 : printf("%c\n", q);

mov eax, DWORD PTR _q$[ebp]
movsx ecx, BYTE PTR [eax]
push ecx
push OFFSET FLAT:??_C@_03BNAH@?$CFc?6?$AA@ ; `string'
call _printf
add esp, 8

; 12 :
; 13 :
; 14 : //char r = *p;
; 15 :
; 16 : return 0;

xor eax, eax

; 17 : }

pop edi
pop esi
pop ebx
add esp, 76 ; 0000004cH
cmp ebp, esp
call __chkesp
mov esp, ebp
pop ebp
ret 0
_main ENDP


C代码如下:

#include <stdio.h>

int main()
{
char* p = NULL;

p = new char;
*p = 'c';

char& q = *p;
printf("%c\n", q);


//char r = *p;

return 0;
}


对应汇编如下:

_TEXT SEGMENT
_p$ = -4
_q$ = -8
$T587 = -12
_main PROC NEAR ; COMDAT

; 4 : {

push ebp
mov ebp, esp
sub esp, 76 ; 0000004cH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-76]
mov ecx, 19 ; 00000013H
mov eax, -858993460 ; ccccccccH
rep stosd

; 5 : char* p = NULL;

mov DWORD PTR _p$[ebp], 0

; 6 :
; 7 : p = new char;

push 1
call ??2@YAPAXI@Z ; operator new
add esp, 4
mov DWORD PTR $T587[ebp], eax
mov eax, DWORD PTR $T587[ebp]
mov DWORD PTR _p$[ebp], eax

; 8 : *p = 'c';

mov ecx, DWORD PTR _p$[ebp]
mov BYTE PTR [ecx], 99 ; 00000063H

; 9 :
; 10 : char& q = *p;

mov edx, DWORD PTR _p$[ebp]
mov DWORD PTR _q$[ebp], edx

; 11 : printf("%c\n", q);

mov eax, DWORD PTR _q$[ebp]
movsx ecx, BYTE PTR [eax]
push ecx
push OFFSET FLAT:??_C@_03BNAH@?$CFc?6?$AA@ ; `string'
call _printf
add esp, 8

; 12 :
; 13 :
; 14 : //char r = *p;
; 15 :
; 16 : return 0;

xor eax, eax

; 17 : }

pop edi
pop esi
pop ebx
add esp, 76 ; 0000004cH
cmp ebp, esp
call __chkesp
mov esp, ebp
pop ebp
ret 0
_main ENDP
Ace丶双鱼 2011-07-22
  • 打赏
  • 举报
回复
编译时能通过 不代表运行时不崩溃!
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bdmh 的回复:]
null指针不能被解引用为一个对象,所以不能被引用
[/Quote]
这句说得也有歧义,null指针是可以引用的,null指针指向的值是不能引用的
pengzhixi 2011-07-22
  • 打赏
  • 举报
回复
我担心的是
char*p=NULL;
char*&h=p;
*h='b';
这样写代码。
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 afreet2006 的回复:]
char* p = NULL; //没有创建对象 其指向的地址为 0x00000000  至少在VS2005上是这样
char& q = *p;//错误,引用不能为空 //引用应该指向一个确定的地址空间

个人理解
[/Quote]
这里q是char不是char*,“引用应该指向一个确定的地址空间“这句话我感觉挺别扭,你看char*p=NULL; char*&ref=p;虽然是不好的代码,但它能很好的运行:
char* p = NULL;
char& q = *p;
//char r = *p;
char* &h = p;//h == NULL
h = "123";
至善者善之敌 2011-07-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wzx19840423 的回复:]
引用 1 楼 pengzhixi 的回复:
in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferen……
[/Quote]

哈哈
afreet2006 2011-07-22
  • 打赏
  • 举报
回复
char* p = NULL; //没有创建对象 其指向的地址为 0x00000000  至少在VS2005上是这样
char& q = *p;//错误,引用不能为空 //引用应该指向一个确定的地址空间

个人理解

  • 打赏
  • 举报
回复
那我是不是能这样理解:
不能引用NULL指针指向的值,因为NULL指针指向的值标准未定义?感觉引用不能为空这句话太含糊了,似乎应该说“不能引用空指针指向的值”
bdmh 2011-07-22
  • 打赏
  • 举报
回复
null指针不能被解引用为一个对象,所以不能被引用
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]
in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer,whi……
[/Quote]
一个空引用,尤其是不能存在于一个明确的计划,因为只有这样,才能创造出这样一个参考,将其绑定到解引用一个空指针的“对象”,这将导致未定义的行为。

你看google翻译多龊。。。
pengzhixi 2011-07-22
  • 打赏
  • 举报
回复
标准说这样做的行为未定义
甚至 char*p=NULL; char*&ref=p;都是不好的代码。
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]
in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer,whi……
[/Quote]
牛哥,说中文吧
pengzhixi 2011-07-22
  • 打赏
  • 举报
回复
in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer,which causes undefined behavior.

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧