#include<iostream>
using namespace std;
void test1();
void test2();
int _tmain(int argc, _TCHAR* argv[])
{
int i(3);
double d;
const int ci(4);
// 1、一般特性
// int &r; // 引用定义时必须初始化
int &r = i; // 引用一旦初始化,其指向不能被改变
double &r10 = d; // 引用指向的对象可能没有初始化,是随机值
const double &r11 = d;
cout<<"d: "<<d<<endl
<<"r11: "<<r11<<endl
<<"r10: "<<r10<<endl;
d = 77.77777;
// 2、 const reference
const int &r1 = ci; // const引用可以指向const对象
const int &r2 = i; // const引用可以指向非const对象
const int &r3 = 25; // const引用可以绑定到右值
// r2 = 10; // 不能通过const引用改变指向的值
i = 10; // r2同时改变
cout<<"i: "<<i<<"\n"
<<"r2: "<<r2<<endl;
// 3、 non_const reference
int &r6 = i; // 非const引用必须指向非const对象
// int &r7 = ci; // 非const引用不能指向const对象
cout<<"i: "<<i<<"\n"
<<"r6: "<<r6<<endl;
r6 = 7; // 可以通过非const引用改变指向的值
cout<<"i: "<<i<<"\n"
<<"r6:"<<r6<<endl;
r6 = d; // 改变指向的值而非改变指向, double转化至int值, r6、i被同时改变
d = 69.9; // r6、i无影响
cout<<"i: "<<i<<"\n"
<<"d: "<<d<<"\n"
<<"r6: "<<r6<<endl;
// 4、const引用类型与指向的类型可能不同,只要可以隐式转换(这一般意味着错误)
const double &r4 = i; // const引用可以指向不同类型的对象,适用隐式转换
cout<<"i: "<<i<<"\n"
<<"r4: "<<r4<<endl;
const int &r5 = d; // 不能保证const引用指向值必定等于引用值
cout<<"d: "<<d<<"\n" // 77.77777
<<"r5: "<<r5<<endl; // 77
// int &r8 = d; // 非const引用必须指向同类型的对象,不适用转换
// double &r9 = i;
test1();
test2();
return 0;
}
// 5、引用作为函数参数
// 避免参数复制的消耗(大型对象特别有用);有些对象不支持复制,只能通过引用传递
ostream& f(ostream& out, const int(&arr)[10])
{
for(int i=0; i!=10; ++i)
out<<arr[i]<<" ";
out<<endl;
return out;
}
// 在函数内改变参数时直接作用于实参本身
// 不支持const实参
void f(int &r)
{
cout<<__FUNCSIG__<<endl;
r = 998;
}
// 支持const与非const实参
void f(const int &r)
{
cout<<__FUNCSIG__<<endl;
}
void test1()
{
int a[10] = {0};
f(std::cout, a);
int i = 10;
f(i);
cout<<i<<endl;
const int ci = 50;
f(ci);
}
// 6、引用作为返回值
// 不要返回局部变量的引用
// 返回局部变量的引用1
const int& fun(int val) // 非引用形参是一种局部变量
{
const int &r = val;
return r;
}
// 返回局部变量的引用2
int& fun()
{
int i = 100;
int &r = i;
return r;
}
// 使用数组的引用避免复制
typedef int (&aref)[10]; // 数组的引用
aref func(aref arr) // 返回数组的引用
{
for(int i=0; i!=10; ++i)
arr[i] = i;
return arr;
}
void test2()
{
// 第一次调用的结果好像是"正确"的
// 这仅仅是因为此局部变量的内存
// 还没来得及被破坏,或未被其他程序占用
// 这一次的访问中“恰好”得到了正确的值,
// 超出作用域之后,局部变量的内存状态已经不定
// 这种访问操作本身是一种未定义行为
int i = 10;
const int i1 = fun(i);
const int &r1 = fun(i);
cout<<i1<<endl; // 10
cout<<r1<<endl; // 随机值
int i2 = fun();
int &r2 = fun();
cout<<i2<<endl; // 100
cout<<r2<<endl; // 随机值
int a[10] = { 0 };
aref arr = func(a); // 现在arr是数组a的引用
for(int i=0; i!=10; ++i)
cout<<a[i]<<" ";
cout<<endl;
a[0] = 999;
for(int i=0; i!=10; ++i)
cout<<arr[i]<<" "; // arr[0]:999
cout<<endl;
}