引用的内存分配

Posted

技术标签:

【中文标题】引用的内存分配【英文标题】:Memory allocation for references 【发布时间】:2012-07-26 01:55:03 【问题描述】:

阅读pointersreferences之间的很多差异。

以下是我所学内容的简要说明。

1。定义指针时分配内存。但是,引用是名称别名,因此没有为其分配内存(Is it correct?)。

2。引用必须在定义时被初始化,因为引用是用一个常量指针实现的,因此不能指向另一个对象。 然而,指针不需要在定义时初始化,因此也可以更改为指向其他对象。

3。引用会自动取消引用。当你写cout << p; 它被编译器自动取消引用并被视为cout << *p;由编译器。

这里,p 是参考。

    对引用的引用是不可能的。每当您声明对引用的引用时,它实际上是对同一变量的引用。 例如

    int i;    
    int &r1=i;    
    int &r2=r1; <-------------------2
    

编译器将语句 2 解释为: 整数 &r2=(*r1) 而 (*r1) 只不过是变量 i 本身。

然而,指向指针的指针是可能的。

5。指针数组是可能的,而引用数组是不可能的(为什么?)。

6。指针的地址是可能的。参考地址是不可能的。它给出了变量的地址。

7。在某些情况下,您必须使用引用。您不能在那里使用指针。 考虑下面的例子:

A a=b+c;

其中 a,b,c 是 A 类的对象。 运算符“+”重载如下:

const A& operator+(const A& o)

     return A(i+o.i);

在此处查看示例代码:http://ideone.com/Q0pE1

这里参数列表中的引用用于保存内存占用。 您不能在参数列表中使用指针,因为您必须在运算符函数中传递对象的地址。 A a=&b + &c; 但是,如果在参数列表中使用了指针,那么我们最终将添加地址而不是对象本身。

我想知道我还有什么遗漏的吗?

什么时候需要指针,什么时候需要参考?

【问题讨论】:

“但是,引用是名称别名,因此没有分配内存”--“引用是用常量指针实现的”--看到矛盾了吗? ;) 这些观点有很多错误,以至于任何答案基本上都可以解释指针和引用是什么。 当你使用指针和引用时,它不是一个或另一个;他们一起工作。在某些情况下,您可能只使用其中一种,但通常情况下,您会同时使用它们。 "指针地址是可能的。引用地址是不可能的。它给出了变量的地址。"在这两种情况下,您都会获得变量的地址。 一般来说,使用引用,除非您需要一种方法来指向空(null)或者如果您遇到无法使用引用的情况。引用清楚地表明 null 是不可能的。 【参考方案1】:

在定义指针时分配内存。但是,引用是名称别名,因此没有为其分配内存

“内存已分配”是什么意思?如果您的意思是堆分配,如newmalloc 或其他,

int val = 5;
int *pVal = &val; //No dynamic memory allocation.

指针有一个大小,就像int 有一个大小一样。但这与“分配”不同。

引用必须在定义时初始化,因为引用是用一个常量指针实现的,因此不能指向另一个对象。

不,引用是在初始化时绑定的,因为引用就是这样工作的。它们是对对象的引用。语言规定它们不可能不受约束,以后它们的约束也不可能改变。因此,有必要在初始化时绑定引用。

编译器如何实现引用完全无关紧要。

引用会自动被取消引用。

没有。 没有可以取消引用。引用只是已存在对象的另一个名称。就是这样。

指针数组是可能的,而引用数组是不可能的(为什么?)。

因为在初始化时必须绑定引用。而且不可能给数组的每个成员一个单独的对象来绑定。因此,您需要在创建数组和绑定引用之间采取一些步骤。这是不允许的。

指针的地址是可能的。参考地址是不可能的。它给出了变量的地址。

引用是已存在对象的另一个名称。您无法获取 name 的地址;你只能得到一个对象的地址。

在某些情况下,您必须使用引用。

没有什么可以阻止您重载 operator+ 以获得指向类型的指针:

A operator+(const A *lhs, const A *rhs) ...

当然,这是一个非成员函数。

哦,作为奖励:

const A& operator+(const A& o)

     return A(i+o.i);

这个坏了。您将 const&amp; 返回给您创建的临时对象。您应该按价值返回它。

【讨论】:

编译器将语句分解,a=b+c为a=b.operator+(c)【当然也会分解=运算符】。那么,'+' 重载的运算符函数如何将指针作为参数? @Greengoblin 尽管已明确说明,但您完全没有抓住重点。如果operator 被定义为类成员,编译器只会执行该转换。如果存在匹配的非成员二进制文件operator+,则这种语法非常好,它可以与lhsrhs 等任何两种类型一起使用。正如 NB 已经说过和证明的那样。

以上是关于引用的内存分配的主要内容,如果未能解决你的问题,请参考以下文章

垃圾回收与内存分配——总结篇

引用传递和动态内存分配之间有啥区别[关闭]

.net 框架中值类型和引用类型的内存分配

类中声明的变量的内存分配

第183天:引用类型和值类型

data.table 中的内存泄漏按引用分组分配