reference :引用

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值