c++基础 面向对象:第二篇(引用)

本文详细介绍了C++中的引用概念,包括引用的初始化、作为函数参数和返回值的使用,以及引用与指针的区别。强调了引用的安全性和效率,指出引用的本质是一个指针常量,不能为NULL,而指针可以。同时讨论了常量引用的应用场景及其优势。
摘要由CSDN通过智能技术生成

1. 引用

引用就是给变量起别名。

语法: 数据类型& 别名 = 变量名;
这里别名等价于变量名;

int a = 10;
int &b = a;
// b 等价于 a;

注意:

  • 引用必须初始化,不初始化的话你都不知道给谁起别名了。
  • 引用一旦初始化就不可以初始化别的变量了(投机取巧的记忆:你见过重复定义的两个变量可以行吗?不可以对吧,那就是不可以了)
eg:引用必须初始化
int &b ; //错误,没有初始化
int a;
int &b = a; //错误 ,a也没有初始化
eg:引用一旦初始化就不可以初始化别的变量了。
int a = 10;
int c = 20;
int &b = a; // 正确
int &b = c; //错误,因为b 引用了 a,就不可以引用别人了。
int &d = a; //正确,虽然a被引用了,可是 d是a另一个别名,相当于a 有两个别名 b 和 d;
			//注意假如d修改了,a和 b也会修改了值

2. 引用做函数的形参

作用:函数传参时们可以利用引用让形参修饰实参,也就是说形参就是实参的别名。
优点:可以简化指针修饰实参。
总结:引用做函数参数,可以和地址传值产生同样的效果。

# include<iostream>
using namespace std;
//交换函数
//1.值传递
void MySwap1(int a, int b)
{
	int t;
	t = a;
	a= b;
	b = t;
}
//2.地址传递
void MySwap2(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}
//3.引用传递
void MySwap3(int &a, int &b)
{
	int t;
	t = a;
	a = b;
	b = t;
}
int main()
{
	int a = 10;
	int b = 20;
	MySwap1(a, b);//值传递,并不会修改实参的数据,修改的是形参的数据,也就是说形参不会修饰实参
	//a b值不变
	cout << "MySwap1的a = " << a << endl;
	cout << "MySwap1的b = " << b << endl;
	
	MySwap2(&a, &b); //地址传递
	//a b 值变了
	cout << "MySwap2的a = " << a << endl;
	cout << "MySwap2的b = " << b << endl;
	
	MySwap3(a, b); // 引用传递
	//a b 值变了
	cout << "MySwap3的a = " << a << endl;
	cout << "MySwap3的b = " << b << endl;

	system("pause");
	return 0;
}

测试结果
在这里插入图片描述

3. 引用做函数的返回值

注意:不要返回局部变量的引用
其实也就是说,出了作用域生命周期会消失的,都不要返回去,这样会野指针,访问非法内存。

int& text1()
{
	int a = 10;
	return a;  //局部变量的形式返回,引用接受的是随机值
}

假如你在vs2013环境下测试的话,它会给你返回10的值,其实这是编译器给你的优化,本质是随机值,要记住,有时候编译器会傻乎乎的给你优化一些结果。

int& text2()
{
	static int a = 10; // 静态变量,不是局部变量
	return a;
}

返回的值正确 a = 10;


4. 引用的本质

引用的本质是一个指针常量(该指针是一个常量,不可以被修改)。这就解释了为什么引用一旦初始化就不可以被修改的原因了。

# include<iostream>
using namespace std;

int main()
{
	int a = 10;
	int &ref = a; 
	//编译器发现是个引用,
	//自动转化为 int* const ref = &a;
	ref = 100; 
	// 编译器发现ref是引用
	//自动转化为 *ref = 100;
	return 0;
}

画个图理解下:
在这里插入图片描述


5. 常量引用

使用场景:假如你知道函数的形参不用修改其值的话,就给这个引用加 const;
这样使用的好处很多:
对于调用者来说,他们可以使用传const和非const的参数;

对于设计者来说:他们假如修改了该cosnt修饰的变量,那么编译时候就会有报错结果提示;

//这个函数的目的就是为了打印ref的值,
//并不想修改ref的值
void text1(const int &ref)
{
	ref = 100; //错误,有const修饰了,常量引用不可以修改其值;
	cout << ref << endl;
}

const引用还可以引用不相同类型的对象

double d = 3.14;

int& a = d; //普通的引用不可以引用不同类型的对象
const int& b = d; //可以编译通过
//上面的语句可以过其实本质是发生了隐式类型转换
即:int tmp = (int)d; const int& b = tmp;
也就是说:const int& b = d; 可以编译通过const有很大作用

6 引用和指针的区别

引用和指针的不同点:

  1. 引用在定义时必须初始化,指针没有要求
  2. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型
    实体
  3. 没有NULL引用,但有NULL指针
  4. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占
    4个字节)
  5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  6. 有多级指针,但是没有多级引用
  7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  8. 引用比指针使用起来相对更安全

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呋喃吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值