什么是引用

        引用是C++编程语言中非常重要的一部分内容,它与C语言中的指针作用类似,但本质却不同,本文将详细介绍C++的引用,如有不足或者缺漏之处,欢迎指正

与指针的区别

        我们说引用和指针作用类似,因为他都可以通过另一个变量名B去引用(指向)变量A,然后通过对各自的操作,访问到A的内容.

int a = 3;
int* p = &a;
int& b = a;
cout <<"指针:"<< * p << "\n引用:" << b;
//两个输出全为3

        指针是一个占内存的变量,占内存大小受编译环境的影响(在32位操作系统上占4字节,在64位操作系统上占8字节),只不过这个内存当中存放的是变量a的地址,所以我们经过取*访问,可以得到a的内容3

        引用不占用内存(底层实现需要内存),它是直接与这个变量用同一块内存空间,所以我们说引用也是给变量起别名,它的本质是指针常量,即  *const p  所以必须要初始化,且不能改变引用关系

int a = 3;
int* p = &a;
int& b = a;
cout << &p << " " << &a << endl;
//输出两个 不同的 地址
cout << &b << " " << &a;
//输出两个 相同的 地址

引用的分类

        引用分为左值引用,右值引用和万能引用,在搞清楚这些引用之前,我们先了解一下什么是左值和右值

        左值: 通俗来说就是可以放在等号左面的值,可以找到对应的内存地址,进行修改,例如已经定义了的变量

        右值: 只能放在等号右边,一般是常量,或者返回值,匿名对象,匿名函数Lambda,这些值的内存地址我们无法找到,也无法更改其中的内容

        左值引用,顾名思义只可以引用左值,右值引用同理,万能引用既可以引用左值也可以引用右值,它们在语法的定义上也有不同

左值引用语法: 数据类型&变量 = 左值;

右值引用语法: 数据类型&& 变量 = 右值;

万能引用语法: const 数据类型& 变量 = 左右值;  万能引用有const修饰,所以也能防止引用修改原数据,起到保护数据的一种效果

	int a;
	int& b = a;
	//int& c = 2;//编译错误,无法将右值绑定到左值引用
	int&& d = 2;
	//int&& e = a;//编译错误,无法将左值绑定到右值引用
	const int& f = a;
	const int& g = 2;

引用做函数参数

        函数的传参形式分为两种,一种是值传递(指针传参在本质上也是值传递,将实参指针的值传给形参指针,只不过内容是变量的内存地址),一种是引用传递

        我们可以使用引用来简化指针修改实参

void m_swap(int& a, int& b) {
	int t = a;
	a = b;
	b = t;
}

int main() {
	int a = 3, b = 4;
	cout << a << " " << b << endl;
    //输出3 4
	m_swap(a, b);
	cout << a << " " << b << endl;
    //输出4 3
	return 0;
}

引用接收函数返回值

        引用可以接收函数的返回值,但是,不要让引用接收返回的局部变量,因为在调用的函数内部,执行return 语句会生成一个临时的匿名对象用来给接收返回值的参数赋值,匿名对象仅存在于当前行,但是局部变量在函数体执行完毕之后会有系统回收对应的资源,导致这一块内存空间被重置,里面的数据成为随机值,这样引用接收的变量也会失去里面的内容

int& test01() {//返回值为int的引用,返回的是变量a而不是a的值
	int a = 10;
	return a;
}

int& test02() {
	static int a = 20;//静态成员的生命周期一直到程序结束
	return a;
}

int main() {
	int& ans01 = test01();
	cout << "ans01= " << ans01 << endl;
	//输出10
	cout << "ans01= " << ans01 << endl;
	//输出随机值

	int& ans02 = test02();
	cout << "ans02= " << ans02 << endl;
	//输出20
	cout << "ans02= " << ans02 << endl;
	//输出20

	return 0;
}

        需要注意的是,有些电脑在第二次输出ans01时还是10,这是因为不同的电脑清理内存的机制可能不同,但决不代表这种行为是安全的,应当注意

注意事项

  • 引用必须初始化,且不能空
  • 引用不能改变引用关系
  • 引用作为返回值可以避免拷贝构造,但是要注意避免返回局部变量引用
  • 引用作为函数参数传参时,也可以避免拷贝构造,但是在函数内部对该对象进行的操作会影响到原本的对象,因为他们在内存上公用同一块内存

相关推荐

  1. 什么引用

    2024-07-11 00:42:01       24 阅读
  2. 模板引擎什么

    2024-07-11 00:42:01       23 阅读
  3. 判断对象是否垃圾的引用计数法有什么问题

    2024-07-11 00:42:01       41 阅读
  4. velocity-engine-core什么?Velocity模板引擎的使用

    2024-07-11 00:42:01       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 00:42:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 00:42:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 00:42:01       58 阅读
  4. Python语言-面向对象

    2024-07-11 00:42:01       69 阅读

热门阅读

  1. 如何从Git仓库中删除大文件并解决推送错误方案

    2024-07-11 00:42:01       23 阅读
  2. Git删除了文件拉取时失败

    2024-07-11 00:42:01       22 阅读
  3. 学习测试练习题

    2024-07-11 00:42:01       24 阅读
  4. QT log日志

    2024-07-11 00:42:01       29 阅读
  5. Angular页面项目以HTTPS方式启动调试

    2024-07-11 00:42:01       22 阅读
  6. ArduPilot开源飞控之AP_VisualOdom

    2024-07-11 00:42:01       20 阅读
  7. 如何实现跨域

    2024-07-11 00:42:01       19 阅读
  8. centos7yum-mysql-community-server安装流程步骤

    2024-07-11 00:42:01       24 阅读
  9. toFixed 四舍五入问题

    2024-07-11 00:42:01       21 阅读
  10. [C++][CMake][嵌套的CMake]详细讲解

    2024-07-11 00:42:01       19 阅读
  11. 65.指针函数和函数指针

    2024-07-11 00:42:01       24 阅读
  12. 网络安全测评技术与标准

    2024-07-11 00:42:01       25 阅读
  13. Qt之多线程编程(QThread)

    2024-07-11 00:42:01       25 阅读
  14. MySQL:left join 后用 on 还是 where?

    2024-07-11 00:42:01       21 阅读