为什么 C++ 有指针了还要引用?
因为加入引用是为了支持operator overloading。这里有一个假设,如果没有引用,那么,用指针来operator overloading操作。
A operator +(const A *a, const A *_a);
那么使用的时候,&a + &b,这样看起来是不是很难受。
而引入引用的概念,既可以满足overload operator,也不失重载value和pointer的灵活性。而且引用还带来一个指针无法替代的特性: 引用临时对象。因为引用必须在定义的时候就赋值,以后无法更改。
发布于 2015-08-24・著作权归作者
绯村剑心
1
我觉得根本是为了解决函数返回值不能是左值的问题 有了引用后可以对表达式赋值
C++为啥要有引用?
因为运算符重载。
C++为啥要有异常?
因为没办法返回一个“空引用”。
因为引用是编译器层的东西, 编译完后并不会占用真正的内存. 而指针是个数据, 是要单独占用内存保存的.
更新一下:
说"引用编译玩后不会占内存",这种说法不太严谨. 应该说引用是个概念, 概念本身不占内存. 而实现引用的通常方式为保存其引用对象的指针,而此指针会占内存,但不是引用占的内存了.
就像类本身不占内存, 但对象会占内存一样,
本来之父也和你一样想的,有指针就够了,一样能实现相应的功能,没必要再多一个语法设施。但后来为了加运算符重载,没有引用的话,前自增的语义就难以说明清楚,这是引入引用概念的历史背景。后来你可以发现,线性容器所重载的下标运算符,迭代器和智能指针所重载的间接访问运算符,输入流和输出流的链式调用,这一切都是离不开引用语义的。
抛开运算符重载的历史因素,引用在大多数场合下完全可以视作指针的语法糖——在底层的汇编的层面讲他们是一样实现的。不过有了引用以后,确实写代码可以方便很多。比如最常见的手法就是利用引用免掉一阶的指针。在 C 里面,你要在函数中修改一个一级指针,形参里得声明成二级指针,但在 C++ 里形参声明成一级指针的引用就可以了。别看只是降了一阶,但人类的思维理解高维的概念很困难,问题降一阶以后考虑问题就可以轻松很多。
有了引用以后,代码也变得简练。以前在 C 里,如果要设计一个函数处理大对象,则不得不以指针做参数,那就不得不声明临时变量去存储中间结果。
Matrix a, b, c;
getMatrixA(&a);
getMatrixB(&b);
addMatrix(&a, &b, &c);
printMatrix(&c);
而在 C++ 里,则完全不需要考虑这些,完全可以以引用当参数,代码又清晰,又不用担心会拷贝而带来效率瓶颈。
print(addMatrix(getMatrixA(), getMatrixB()));
引用是很早就有的 c++ 概念,可以视为指针的语法糖。
右值引用是c++11 里面为了移动语义提出的,也就是和这种类型: T&&。
移动语义就是为了提高运行时效率,相对于拷贝和赋值提出了一种更高效的可选的实现策略,这样就能通过 std::move 明确指示编译器执行资源数据的移动,而不是拷贝。这样就提高了效率。也就是说,如果只有引用,那么编译器“并不敢”擅自使用移动来完成拷贝,赋值这个动作(移动意味着源对象会变成一个“空壳子“),因为它不知道用户是否将来还会再用到这个对象。
引入 T&& 的意思就是明确的告诉编译器,我这个对象后续就不用了,你放心的移动吧!
此外就是 std::forward 是为了让模板可以正确推断成右值引用而使用移动语义优先。
至于什么是左值,右值,就到 Value categories 去查询吧。