引用不占存储空间的话,他怎么记录相关信息,如他所引用的对象?

xunyingren 2009-06-19 04:31:42
声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。

这话怎么理解?引用不占存储空间的话,他怎么记录相关信息,如他所引用的对象?
...全文
119 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
机智的呆呆 2009-06-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sm_dlkey001 的回复:]
编译器记录该引用
[/Quote]
up,编译器维护一个符号表,记录着变量名称和内存的映射关系,基本上是一个变量名映射一块内存区域。编译器在编译程序时
依靠符号表,把对同一变量的操作都正确映射到同一内存的操作。而引用的作用就是在符号表中对某一块内存区域,添加额外
的变量名对这块内存映射。也就是现在有两个变量的名映射同一块内存区域。所以此时引用可以没有额外存储空间,对引用的操
作可以直接通过符号表映射所引用的变量的内存空间里去。程序编译成2进制后,里面就没有变量名了,全是对特定地址内存的操作了。
sm_dlkey001 2009-06-20
  • 打赏
  • 举报
回复
编译器记录该引用
机智的呆呆 2009-06-20
  • 打赏
  • 举报
回复
It is unspecified whether or not a reference requires storage (3.7).
ISO/IEC 14882:2003(E) p164 的8.3.2节。
mengde007 2009-06-19
  • 打赏
  • 举报
回复
尚在争论中……
huntjap 2009-06-19
  • 打赏
  • 举报
回复
申明引用的是个变量当然要占内存!!!!
Jalien 2009-06-19
  • 打赏
  • 举报
回复

你是在release下启动优化的吧,不知道release版本到底优化了哪些。
开了/O1优化,从汇编代码看感觉a都不要分配内存单元了,直接往寄存器送,我试过写个类,让对象相加,
我发现我创建对象时根本就没有看到构造函数的调用,输出时压人的都是已经计算好了的数。

我的测试代码是这样的:

#include<iostream>
using namespace std;

class TestRef{
friend ostream& operator<<(ostream& os,TestRef& a);
public:
TestRef(int i,int j):num(i),index(j){}
const TestRef operator+(const TestRef& t)const{
return TestRef(this->num+t.num,this->index+t.index);
}
private:
int num;
int index;
};

ostream& operator<<(ostream& os,TestRef& a){
os<<a.num<<" "<<a.index<<endl;
return os;
}

int main(){
TestRef tr1(2,5);
TestRef tr2(3,7);
TestRef &tr3=tr1;
tr3=tr1+tr2;
cout<<tr3<<endl;
}


VS 2008中release版本打开O1优化后的反汇编代码:

int main(){
TestRef tr1(2,5);
TestRef tr2(3,7);
TestRef &tr3=tr1;
tr3=tr1+tr2;
cout<<tr3<<endl;
011E1000 mov ecx,dword ptr [__imp_std::cout (11E2058h)]
011E1006 push esi
011E1007 push dword ptr [__imp_std::endl (11E2038h)]
011E100D mov esi,ecx
011E100F push 0Ch ;5+7=12
011E1011 push 5 ;2+3=5
011E1013 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11E2044h)]
011E1019 push eax
011E101A call std::operator<<<std::char_traits<char> > (11E1100h)
011E101F pop ecx
011E1020 mov ecx,eax
011E1022 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11E2044h)]
011E1028 mov ecx,eax
011E102A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11E2040h)]
011E1030 push dword ptr [__imp_std::endl (11E2038h)]
011E1036 mov ecx,esi
011E1038 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11E2040h)]
}

[Quote=引用 11 楼 Demon__Hunter 的回复:]
Assembly code
int main()
453: {
00401C60 55 push ebp
00401C61 8B EC mov ebp,esp
00401C63 51 push ecx
454:
455: int a=1024;
456: int &b=a;
457: int k;
458: cin>>k;
00401C64 8B 0D 2C 62 40 00 mov ecx,dword ptr [__imp_std::cin (40622Ch)]
00401C6A 56 push esi ;入栈保护esi
00401C6B 8D 45 FC lea eax,[k]
00401C6E 50 push eax
00401C6F BE 00 04 00 00 mov esi,400h ;在开了/01优化情况下,a的值直接保存在esi中,
;也就是说a的存储空间对应esi寄存器中。
00401C74 FF 15 1C 62 40 00 call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (40621Ch)]
459: if(k==0)
00401C7A 83 7D FC 00 cmp dword ptr [k],0
00401C7E 75 01 jne main+21h (401C81h)
460: {
461: b++;
00401C80 46 inc esi ;从这来看引用b根本没有分配空间,对引用b的操作直接映射到a对应的
;内存操作,也就是说a b都是esi这块空间的别名,
462: }
463: b++;
[/Quote]
pengzhixi 2009-06-19
  • 打赏
  • 举报
回复
只看,不发表意见了.
pathuang68 2009-06-19
  • 打赏
  • 举报
回复
老问题了
机智的呆呆 2009-06-19
  • 打赏
  • 举报
回复

448: #include<iostream>
449: using namespace std;
450:
451:
452: int main()
453: {
00401C60 55 push ebp
00401C61 8B EC mov ebp,esp
00401C63 51 push ecx
454:
455: int a=1024;
456: int &b=a;
457: int k;
458: cin>>k;
00401C64 8B 0D 2C 62 40 00 mov ecx,dword ptr [__imp_std::cin (40622Ch)]
00401C6A 56 push esi ;入栈保护esi
00401C6B 8D 45 FC lea eax,[k]
00401C6E 50 push eax
00401C6F BE 00 04 00 00 mov esi,400h ;在开了/01优化情况下,a的值直接保存在esi中,
;也就是说a的存储空间对应esi寄存器中。
00401C74 FF 15 1C 62 40 00 call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (40621Ch)]
459: if(k==0)
00401C7A 83 7D FC 00 cmp dword ptr [k],0
00401C7E 75 01 jne main+21h (401C81h)
460: {
461: b++;
00401C80 46 inc esi ;从这来看引用b根本没有分配空间,对引用b的操作直接映射到a对应的
;内存操作,也就是说a b都是esi这块空间的别名,
462: }
463: b++;
464:
465: cout<<a<<endl;
00401C81 FF 35 20 62 40 00 push dword ptr [__imp_std::endl (406220h)]
00401C87 8B 0D 24 62 40 00 mov ecx,dword ptr [__imp_std::cout (406224h)]
00401C8D 46 inc esi
00401C8E 56 push esi
00401C8F FF 15 28 62 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (406228h)]
00401C95 8B C8 mov ecx,eax
00401C97 FF 15 30 62 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (406230h)]
466: system("pause");
00401C9D 68 FC 37 40 00 push offset string "pause" (4037FCh)
00401CA2 FF 15 D0 62 40 00 call dword ptr [__imp__system (4062D0h)]
00401CA8 59 pop ecx
467: return 0;
00401CA9 33 C0 xor eax,eax
00401CAB 5E pop esi
468: }
00401CAC C9 leave
00401CAD C3 ret
机智的呆呆 2009-06-19
  • 打赏
  • 举报
回复
用vc写个程序,在不优化和开优化情况下,反编译看下就知道le,未开优化时,引用用指针实现。
开优化情况下,引用没有存储空间。
laibach0304 2009-06-19
  • 打赏
  • 举报
回复
引用和指针占同样的空间
机智的呆呆 2009-06-19
  • 打赏
  • 举报
回复
up把,引用可以分配内存,也可以不分配,关键看编译器处理的。
Jalien 2009-06-19
  • 打赏
  • 举报
回复
原来早有人放广告了 多谢![Quote=引用 3 楼 lingyin55 的回复:]
老问题了,看这个帖子
http://topic.csdn.net/u/20090519/13/0219aaed-23d2-4d44-947c-f3f33f1ff367.html
[/Quote]
woods2001 2009-06-19
  • 打赏
  • 举报
回复
C++语法
编译器做这些事情
如果你想深入了解可以看看编译原理
但是不建议花大力气看··
Jalien 2009-06-19
  • 打赏
  • 举报
回复
我觉得会占用内存的。
我以前发过一个贴,也是关于引用是否分配内存的,大家可以看看:
质疑:引用不分配内存? http://topic.csdn.net/u/20090519/13/0219aaed-23d2-4d44-947c-f3f33f1ff367.html
送你广告没商量
帅得不敢出门 2009-06-19
  • 打赏
  • 举报
回复
从汇编级看,是分配了空间的,你反汇编一下就明白了
编译器可以用寄存器等来表示记录的


lingyin55 2009-06-19
  • 打赏
  • 举报
回复
老问题了,看这个帖子
http://topic.csdn.net/u/20090519/13/0219aaed-23d2-4d44-947c-f3f33f1ff367.html
yang_e_2009 2009-06-19
  • 打赏
  • 举报
回复
按照<<C++ primer>>第4版的说法
"引用只是对象的另一个名字"
yyyapple 2009-06-19
  • 打赏
  • 举报
回复
引用只是c++的一种语义,底层实现上还是需要借助指针的

65,211

社区成员

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

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