我正在学习C++中的引用。特别是,我了解到参考文献并不是实际的对象。相反,它们指的是其他对象。也就是说,引用只是其他对象的别名。
然后我看到这个上面写着:
重要提示:尽管引用通常使用底层汇编语言中的地址来实现,但请不要将引用视为指向对象的有趣指针引用是对象,只是使用另一个名称。它既不是指向对象的指针,也不是对象的副本它就是对象没有任何C++语法可以让您对引用本身进行操作,而不必对它所引用的对象进行操作。
我知道上面的引用意味着我们不能对引用本身进行操作,而将其与引用所指向的对象分开,但它仍然似乎意味着"引用是对象";。
此外,我还看到了下面的句子:
在ISO C++中,引用不是对象。因此,它不需要任何内存表示。
我没有第二句话的链接,但我在SO的一篇帖子中读到了。
我的问题是,假设第二句话也来自标准(可能不是这样),这两句话是否相互矛盾。或者至少第一句话有误导性。哪一个是正确的。
我目前的理解(通过阅读C++Primer第5版等书籍)是,引用是对象的别名。这让我想到他们不应该在记忆中占据任何空间。
重要注意:尽管引用通常是使用底层汇编语言中的地址实现的,但请不要将引用视为指向对象的有趣指针。引用是对象,只是有另一个名称。。。
注释是非正式的,通常不应被解释为严格的规则。如果一种解释与标准规则相矛盾,那么这种解释就是错误的。
引用和对象是不同种类的实体。引用不是与其命名的对象不同的对象。不可能形成指向引用的指针。A";指向引用的指针";甚至不是有效的类型类别。
该注释试图表示引用";是";它命名的对象的意义是,使用引用就是使用被引用的对象。
我正在考虑确认引用是否占用任何空间
引用占用空间或不占用空间。这取决于语言实现来判断它在每种情况下是否需要空间。
标准报价:
[dcl.ref]未指定引用是否需要存储
在标准规范之外,如果您想要一个使用空格的引用示例,请尝试向类添加一个引用成员,您很可能会发现类的大小会增加。
由于指针占用空间,引用也应该占用空间。。。
指针在标准指定的抽象机器中确实占用空间。但是,如果你从未观察过存储,那么在实践中完全有可能从未存在过存储。引用和指针之间的一个显著区别是,不能直接观察引用的存储。
哲学家:;如果一棵树落在抽象机器中,周围没有人观察它,它会产生影响吗">
乐观主义者:;如果我能帮上忙就不行;
引用提供了另一种引用对象的方式。这在通过引用将参数传递给函数时尤其有用。更正式地说,引用是绑定到变量的别名,在本例中包括匿名临时。
幸运的是,我们不需要关心它们是如何实现的。这是编译器的工作,技术各不相同。C++标准不要求它们占用任何内存。
是一种区分引用类型的方法。不可分性实际上更多的是不能将引用绑定到任何其他变量。参见
#include <iostream>
#include <type_traits>
int main() {
int a = 0;
int& ref = a;
std::cout << (
std::is_reference<decltype(ref)>::value ? "pay me a bonusn" : "reformat my hard diskn"
);
std::cout << (
std::is_reference<decltype(a)>::value ? "pay me a bonusn" : "reformat my hard diskn"
);
}
最后注意,&a
和&ref
必须始终相同。
第一句话实际上是说引用与对象不可分离。
。。。似乎仍然暗示着";引用是对象";。
这实际上意味着引用是对象的一个不可分离的非第一类别名,正如您第一次所说的那样。
这些讨论的困难在于;对象";已经与大多数不太正式的上下文中使用的含义不同。
让我们简单地开始:
int a;
通常会被描述为声明一个整数对象a
,对吧?实际上是
- 声明一个整数对象
- 将名称
a
绑定到适当作用域中的该对象
现在,如果我们写
int &b = a;
我们可以说b
是对象,就像我们可以说a
是对象一样。事实上,两者都不正确,但考虑到非正式文本已经使用了后者,这并不比更糟。
我们应该说名称b
与名称a
指代相同的对象。这与将其称为别名完全一致,但非正式或介绍性文本如果写";。。。由名称CCD_ 11引用的整数对象"无处不在,而不仅仅是";整数CCD_ 12";。
至于占用内存。。。这取决于情况。如果我在一个函数中为一个对象引入100个别名,如果编译器没有将它们折叠起来,我会非常惊讶(当然,它们可能仍然显示在调试符号中)。删除多余的名称不会丢失任何信息。
如果我通过引用一个非内联函数来传递一个参数,一些实际信息正在被传递,并且这些信息必须存储在某个地方。
实际上是一个什么样的引用"是";没有多大意义:你可以说它是被引用的对象,或者说它是它的别名,这些说法在某种意义上都是正确的。
int main()
{
int a(0);
int& ref(a);
ref = 1; // Will actually affect the value of a
return 0;
}
让我们逐行看这个程序。
int a(0);
在堆栈上分配一些内存(通常为4字节)来保存一个整数int& ref(a);
不一定分配内存,它是否实际分配内存取决于编译器。从这个意义上说,ref
本身并不是一个对象:它只是a
的一个别名,另一个名称。这就是第二句话中";引用不是对象";。(请注意,有时,例如,当在编译时无法知道引用了什么对象时,引用必须为对象的地址保留额外的空间。在这种情况下,引用只是指针的语法糖。)- CCD_ 17将CCD_ 18的值设置为1。从这个意义上讲,您可以将
ref
看作与a
完全相同的对象任何操作";关于";引用将实际对被引用的对象进行操作这就是第一句话中";它就是对象