C++中使用引用

注释包含许多关键点以及注意事项

#include <iostream>

using namespace std;

/*
C++中引用可以看做是一个数据的别名,通过别名和原来的名字都能够找到这份数据
引用的定义方式类似于指针,只是用&取代了*
type & name = data;
注:
	引用必须在定义的时候初始化,并且要从一而终,不能引用其它数据,这点有点类似于常量(const变量),
	而且必须绑定到变量、对象等上去,不能绑定到常量上去。
	引用在定义时需添加 & , 使用时候无需加 &, 使用时加&表示取地址(定义变量时&在左边是引用,右边是取地址)
	引用作为返回参数的时候,返回的数据不能是局部变量Fun3
*/
void quoteFun(void)
{
	int a = 99;
	int &r = a;
	cout << a << " " << r << endl;
	cout << &a << " " << &r << endl;
	r = 10;
	cout << a << " " << r << endl;
}
void swap1(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}
void swap2(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
void swap3(int &r1, int &r2)//形参引用会改变传入的值
{
	int temp = r1;
	r1 = r2;
	r2 = temp;
}
void quoteFun2(void)
{
	int num1 = 3, num2 = 5;
	swap1(num1, num2);//形参并没有进行替换
	cout << num1 << " " << num2 << endl;
	num1 = 3, num2 = 5;
	swap2(&num1, &num2);//常见的指针的方式
	cout << num1 << " " << num2 << endl;
	num1 = 3, num2 = 5;
	swap3(num1, num2);//用引用的方式实现替换
	cout << num1 << " " << num2 << endl;
}
int &quoteTest(int &r)
{
	int m = r + 10;
	//return n;
	return m;
}
void quoteFun3(void)
{
	int num1 = 10;
	int num2 = quoteTest(num1);
	cout << num1 << " " << num2 << endl;
	int &num3 = quoteTest(num1);
	int &num4 = quoteTest(num3);
	cout << num3 << " " << num4 << endl;
}
int num = 99;
class A
{
public:
	A();
private:
	int n;
	int &r;
};
A::A() :n(0), r(num) {}
void quoteFun4(void)
{
	/*
	变量是要占用内存的,虽然我们称 r 为变量,但是通过&r获取到的却不是 r 的地址,
	而是 a 的地址,这会让我们觉得 r 这个变量不占用独立的内存,它和 a 指代的是同一份内存。
	*/
	A *a = new A();
	cout << sizeof(A) << endl;
	cout << hex << showbase << *((int*)a + 1) << endl;
	cout << &num << endl;
	/*
	从运行结果来看
		成员变量 r 是占用内存的,如果不占用的话,sizeof(A)的结果应该为 4。
		r 存储的内容是0x442000,也即变量 num 的地址。

	其实引用只是对指针进行了简单的封装,它的底层依然是通过指针实现的,
	引用占用的内存和指针占用的内存长度一样,在 32 位环境下是 4 个字节,
	在 64 位环境下是 8 个字节,之所以不能获取引用的地址,是因为编译器进行了内部转换。
	*/
}
/*
引用和指针的其它区别
1、引用必须在定义时初始化,并且以后也要从一而终,不能再指向其他数据;
而指针没有这个限制,指针在定义时不必赋值,以后也能指向任意数据。
2、指针可以有多级,但是引用只能有一级,例如,int **p是合法的,
而int &&r是不合法的。如果希望定义一个引用变量来指代另外一个引用变量,那么也只需要加一个&
3、指针和引用的自增(++)自减(--)运算意义不一样。对指针使用 ++ 表示指向下一份数据,
对引用使用 ++ 表示它所指代的数据本身加 1;自减(--)也是类似的道理。
*/
/*
指针只能指向内存,不能指向寄存器和硬盘
例如:表达式的结果、函数的返回值,它们可能放在寄存器也可能放在内存
放在寄存器中用&来获取它们的地址是不对的
int m = 10, n=20;
int *p = &(m + n);
int *p2 = &(n + 100);
bool *p4 = &(m < n);
这些结果都会被放到寄存器中
int fun()
{
	int n = 100;
	return n;
}
int *p3 = &(fun());//这个临时结果也会存在寄存器中

常量表达式的值虽然在内存中,但是没有办法寻址,所以也不能使用&来获取它的地址,更不能用指针指向它。
引用和指针在本质上是一样的,引用仅仅是对指针进行了简单的封装。故引用也只能对内存进行取址
*/
bool is0dd(int &n)
{
	if (n % 2 == 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}
void quoteFun5(void)
{
	//函数参数是引用类型,只能传递变量,不能传递常量或者表达式。
	int a = 100;
	is0dd(a);//正确
	//is0dd(a+9);//错误
	//is0dd(3);//错误
/*
引用不能绑定到临时变量,但是加了const关键字后,可以绑定到临时数据了
常引用绑定到临时数据时,编译器会创建一个新的、无名的变量,然后将引用绑定到该临时变量
将函数修改
bool is0dd(const int &n);
is0dd(a+9);
is0dd(3);
正常运行
注:
	给引用添加 const 限定后,不但可以将引用绑定到临时数据,还可以将引用绑定到类型相近的数据,
	这使得引用更加灵活和通用,它们背后的机制都是临时变量。
char c = '@';
char &r3 = c;  //正确
const int &r4 = c;  //正确
将引用类型形参添加const限制理由有三:
	使用 const 可以避免无意中修改数据的编程错误;
	使用 const 能让函数接收 const 和非 const 类型的实参,否则将只能接收非 const 类型的实参;
	使用 const 引用能够让函数正确生成并使用临时变量。
*/
}

int main(void)
{
	quoteFun4();
	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值