在使用上,我们要把引用当成另一个对象的“别名”
即看到一个引用,我们可以直接把它脑补成原来的对象
这样会衍生出引用的一系列特性(与指针相比):
实际上如果查看汇编代码的话,引用是通过指针实现的
int a = 55;
int &b = a;
int * const c = &a;
这一段代码会被编译器翻译为:
movl $55, -28(%rbp) // *(-28(%rbp)) =55; 即 int a = 55
leaq -28(%rbp), %rax
movq %rax, -16(%rbp) // -16(%rbp) = -28(%rbp); 即 int &b = a;
leaq -28(%rbp), %rax
movq %rax, -24(%rbp) // -24(%rbp) = -28(%rbp); 即 int * const c = &a;
可以看到虽然b是a的引用,但在实现上并不是简单的替换,而是生成了b的空间存储a的地址,和指针c的实现是相同的。即引用在实现上相当于是一个指针常量 。[指针常量与常量指针]
我们可以看到,引用只是一种概念上的抽象,那在C++中为什么同时存在引用和指针呢?什么情况下使用引用呢?
结论1:C++的引用主要是为了支持运算符重载;指针的存在主要是为了兼容C语言。[为什么 C++ 有指针了还要引用?]
结论2:用户自定义类型最好用引用传参,这样可以避免不必要的构造函数和析构函数调用;对于内置(C-like)类型,按值传参会比按引用传参更高效。[内置类型传值效率高的原因]
有了这两层对引用的理解,我们就可以解释引用的下面这些特性了:
引用++
是原来的对象执行自增(引用是对象的别名)sizeof(引用)
的大小是被绑定的对象的大小(引用是对象的别名)原文:https://www.cnblogs.com/harrypotterisdead/p/14696739.html