引用
左值引用
下面的代码不符合规范:
左值引用需要给它赋一个初始值。
而且这个值不能是右值。
#include<iostream>
using namespace std;
int & test()
{
int a=5;
cout<<&a<<endl;
cout<<a<<endl;
return a;
}
int main()
{
int &s=test();
cout<<&s<<endl;
cout<<s<<endl;
return 0;
}
执行结果:
栈区局部变量超出作用域后,系统自动销毁。
传左值引用:
#include<iostream>
using namespace std;
int & test(int &a)
{
cout<<&a<<endl;
cout<<a<<endl;
return a;
}
int main()
{
int b=5;
cout<<&b<<endl;
cout<<b<<endl;
int &s=test(b);
cout<<&s<<endl;
cout<<s<<endl;
return 0;
}
执行结果:
右值引用
传右值引用:
#include<iostream>
using namespace std;
int & test(int &a)
{
cout<<&a<<endl;
cout<<a<<endl;
return a;
}
int main()
{
int &&b=5;
cout<<&b<<endl;
cout<<b<<endl;
int &s=test(b);
cout<<&s<<endl;
cout<<s<<endl;
return 0;
}
执行结果:
返回右值(没有引用):
这说明了进行右值引用后,右值变成了左值。
#include<iostream>
using namespace std;
int && test()
{
return 5;
}
int main()
{
int &&s=test();
cout<<&s<<endl;
cout<<s<<endl;
return 0;
}
执行结果
超出作用域后,右值被销毁。
研究一下下面的示例:
在这里插入代码片#include<iostream>
using namespace std;
int* test(int *a)
{
cout<<&a<<endl;
cout<<a<<endl;
cout<<*a<<endl;
return a;
}
int main()
{
int a=5;
cout<<&a<<endl;
cout<<a<<endl;
int *b=test(&a);
cout<<b<<endl;
cout<<*b<<endl;
return 0;
}
执行结果:
问:执行完test(&a)后,销毁的是什么?
答:销毁的是形参中存储指针变量地址的内存。
#include<iostream>
using namespace std;
int** test(int *a1)
{
cout<<&a1<<endl;
cout<<a1<<endl;
cout<<*a1<<endl;
return &a1;
}
int main()
{
int a=5;
cout<<&a<<endl;
cout<<a<<endl;
int **b=test(&a);
cout<<b<<endl;
cout<<*b<<endl;
cout<<**b<<endl;
return 0;
}
执行结果:
0x7ffff2cc8fc8表示的是&a1的值,&a1这个地址存放的是a1(0x7ffff2cc8fe4)的值,a1这个地址存放的是*a1(5)的值,test执行完后,会销毁&a1(0x7ffff2cc8fc)这个地址值所存放的数据(0x7ffff2cc8fe4),&a1是一个地址,没有直接用来存放它的内存单元。
看看下面的例子:
#include<iostream>
using namespace std;
int& test()
{
int a=50;
cout<<&a<<endl;
return a;
}
int main()
{
int &a=test();
cout<<a<<endl;
cout<<&a<<endl;
a=7;
cout<<a<<endl;
int b=test();
cout<<b<<endl;
cout<<&b<<endl;
return 0;
}
执行结果:
引用的本质就是给右操作数起一个别名,非引用的本质就是复制右操作数。
返回值为非引用类型的return 的本质是返回一个右值。验证如下:
#include<iostream>
using namespace std;
int test()
{
int a=50;
cout<<&a<<endl;
return a;
}
int main()
{
int &&a=test();
cout<<&a<<endl;
cout<<a<<endl;
return 0;
}
执行结果:
结果说明返回值为非引用的话返回的是返回对象的副本。
再看下面的例子:
#include<iostream>
using namespace std;
int test()
{
int a=1;
return a;
}
int &test1()
{
int a=1;
return a;
}
int &&test2()
{
int a=5;
return 5;
}
int test3()
{
int a=5;
return 5;
}
int main()
{
int b;
b=test();
cout<<b<<endl;
b=test1();
cout<<b<<endl;
b=test2();
cout<<b<<endl;
b=test3();
cout<<b<<endl;
return 0;
}
执行结果:
说明了非引用类型的数据可以接收引用类型的返回值。