网站首页 > 基础教程 正文
引言:什么是引用
在C++中,引用实际上是某个变量(对象)的别名,也可以说就是外号。引用并不是一个独立的对象,它只是一个别称,用来直接访问已经存在的内存地址。举例来说腾讯的别名就是鹅厂,字节跳动的别名就是宇宙厂。接下来的介绍将围绕着别名和引用的底层实现,来深入浅出的剖析一下引用的概念。
C++引用的语法基础
1.引用的定义
上面我们说到引用是一个变量的别名。一旦引用被定义,它就必须绑定到某个已有的变量,之后这个引用将始终代表该变量,无法更改绑定。其实这里也很好理解,给腾讯起了别名叫鹅厂,如果之后叫阿里巴巴也叫鹅厂,这就乱了套了 。实例代码如下。
#include <iostream>
int main() {
int a = 10;
int b = 20;
int &ref = a; // ref 是 a 的引用
std::cout << "ref 最初引用 a: " << ref << std::endl; // 输出 10
ref = b; // 这里并不是更改 ref 的绑定,而是将 b 的值赋给了 a
std::cout << "修改 ref 后,a 的值变为: " << a << std::endl; // 输出 20
std::cout << "b 的值依旧是: " << b << std::endl; // 输出 20
return 0;
}
这里发现从语法上就杜绝了更改绑定这个选项。然后说一说为什么对ref做了更改a的值也会变,因为从语法上而言对引用的任何操作都是对a的操作,我们平时说的鹅厂怎么怎么样也都是在说腾讯;那么从底层而言引用并不占用额外的内存空间。它仅仅是原对象的一个别名,编译器在生成代码时会直接替换成原对象的地址或值,直接操作原对象。
2.引用的语法
引用的语法非常简单,在类型名后面直接加上“&”即可。
type &referenceName = variableName;
3.引用的初始化
引用在定义时必须进行初始化,即必须绑定到某个已有变量。这意味着不能有“空引用”或“未初始化的引用”。这个也很好理解,在起别名鹅厂的时候,必须让它对应上一个对象(腾讯),如果没有这个绑定的对象,那这个别名起的还有什么意思。
int &ref; //报错 error: 'ref' declared as reference but not initialized
引用的实际应用场景
1. 函数参数传递
这是日常开发中引用的应用最多的场景了。通过引用传递参数,可以避免值传递时的拷贝操作,尤其是在处理大对象时提高性能。同时,函数可以通过引用参数直接修改调用者提供的变量。
void increment(int &x) {
x++; // 直接修改 x 的值
}
int main() {
int a = 5;
increment(a); // 通过引用传递,a 的值被修改
std::cout << "a = " << a << std::endl; // 输出 6
return 0;
}
其实这里大家也发现了,通过传递指针和解引用也能做到这一点,即避免的拷贝操作又能直接修改,那么为什么不用指针呢,卖个关子,等下篇会出一篇专门介绍指针和引用的比较。
2.常量引用
常量引用允许我们通过引用来访问一个对象,而不允许修改它。这在函数参数传递中尤为常见,既避免了拷贝操作,又保护了原对象不被修改。
void printValue(const int &x) {
std::cout << "Value: " << x << std::endl;
}
int main() {
int a = 10;
printValue(a); // 传递 a 的常量引用,a 不会被修改
return 0;
}
3.使用引用避免拷贝
引用成员变量可以避免对象的深拷贝。对于大型对象或需要共享数据的场景,通过引用成员变量可以节省内存和提高性能。
class LargeObject {
public:
void doSomething() {
std::cout << "Doing something with a large object!" << std::endl;
}
};
class MyClass {
private:
LargeObject &obj; // 引用成员变量
public:
MyClass(LargeObject &lo) : obj(lo) {}
void useObject() {
obj.doSomething();
}
};
int main() {
LargeObject lo;
MyClass myObj(lo); // 不进行拷贝,直接引用 lo
myObj.useObject(); // 输出 "Doing something with a large object!"
return 0;
}
引用的底层实现
引用的底层实现,说到底就是利用指针做了一个语法糖。
int x = 10;
int &ref = x;
编译器会将int &ref = x;翻译为int *const ref = &x;,然后在使用ref的地方实际上会操作*ref。
这也就是它如何能直接操作对象,如何初始化后便不能再修改的底层原理。但是从代码上来看确实是简洁了很多很多。
总结
引用就是起别名。通过这个外号来直接操作原对象。代码会相当的整洁美观。必须初始化,且不能中途更改。最主要的应用就是函数传递参数的过程中能有效的避免拷贝,大大的提升了效率。底层实现,就是基于指针的一个语法糖。另外多说一嘴,上面说的所有引用都是左值引用,有左值引用那就有右值引用,右值引用那就下篇再讲(挖的坑好多)。诸位,相信看完这篇各位的内功又进一步,让我们继续加油!
猜你喜欢
- 2024-10-09 探讨C++中引用变量的原理以及特点
- 2024-10-09 C++编程:函数参数类型-引用、指针、值
- 2024-10-09 C++ 引用,如何定义对象的常引用?linux C++第50讲
- 2024-10-09 c++引用详解 c++引用怎么写
- 2024-10-09 c语言-指针和引用的理解 c中指针和引用的区别
- 2024-10-09 2 C++重点概念理解系列2-理解引用的本质
- 2024-10-09 C++|指针,理解指针从为什么需要指针这种数据类型开始
- 2024-10-09 C|函数指针和指针函数的联系与区别
- 2024-10-09 const、指针、引用的关系 const与指针的关系
- 2024-10-09 C++ API设计:指针vs引用,应对空值、内存分配和可选参数选择之道
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)