引用
引用是对已经存在的对象或函数取别名
引用的类型
- 左值引用:the declaration S& D; declares D as an lvalue reference to the type determined by decl-specifier-seq S.
- 右值引用:the declaration S&& D; declares D as an rvalue reference to the type determined by decl-specifier-seq S.
引用必须被有效的初始化。
引用到底是什么
在c++标准里,
引用不是对象,所以,引用可以不占任何存储空间
在具体的编译器实现中,引用通常是用指针来实现的。由于,需要遵从c++标准,所以,在抽象上,我们要认为引用不是对象。
因为引用不是对象,所以,没有引用的数组,没有引用的引用,没有指向引用的指针
int& a[3]; // error
int&* p; // error
int& &r; // error
左值引用
#include <iostream>
#include <string>
int main()
{
std::string s = "Ex";
std::string& r1 = s;
const std::string& r2 = s;
r1 += "ample"; // modifies s
// r2 += "!"; // error: cannot modify through reference to const
std::cout << r2 << '\n'; // prints s, which now holds "Example"
}
右值引用
-
右值引用绑定到右值对象。
扩展了临时变量的生存期。 #include <iostream> #include <string> int main() { std::string s1 = "Test"; // std::string&& r1 = s1; // error: can't bind to lvalue const std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime // r2 += "Test"; // error: can't modify through reference to const std::string&& r3 = s1 + s1; // okay: rvalue reference extends lifetime r3 += "Test"; // okay: can modify through reference to non-const std::cout << r3 << '\n'; }
-
右值引用绑定到xvalue对象
#include <iostream> using namespace std; void f(int&& a){ a=20; } int main(){ int b=10; f(std::move(b)); cout<<b<<endl; return 0; }
例子:
#include <iostream> #include <utility> void f(int& x) { std::cout << "lvalue reference overload f(" << x << ")\n"; } void f(const int& x) { std::cout << "lvalue reference to const overload f(" << x << ")\n"; } void f(int&& x) { std::cout << "rvalue reference overload f(" << x << ")\n"; } int main() { int i = 1; const int ci = 2; f(i); // calls f(int&) f(ci); // calls f(const int&) f(3); // calls f(int&&) // would call f(const int&) if f(int&&) overload wasn't provided f(std::move(i)); // calls f(int&&) }