C++引用类型全解析

 更新时间:2026年07月14日 09:30:01   作者:小小晓.  
这篇文章给大家介绍C++引用类型全解析,本文用生动比喻帮你理清左值引用、右值引用核心区别,学会移动语义提升代码性能,感兴趣的朋友跟随小编一起看看吧

时隔很久终于又开始补学之前的知识了,话不多说,开始整理笔记

类型分类

1.内置类型(属于基本类型)

整型(Integer Types)
int:标准整型,通常为4字节。
short:短整型,通常为2字节。
long:长整型,通常为4或8字节
long long:更长的整型,通常为8字节。
unsigned:无符号整型,不支持负数。
unsigned short、unsigned long、unsigned long long:对应的无符号版本。
字符型(Character Types)
char:字符型,通常为1字节。 (char c=“a”;)
wchar_t:宽字符型,通常为2或4字节(用于表示Unicode字符)。
char16_t、char32_t:用于表示UTF-16和UTF-32编码的字符。
浮点型(Floating Point Types)
float:单精度浮点型,通常为4字节。
double:双精度浮点型,通常为8字节。
long double:扩展精度浮点型,通常为8字节或16字节(取决于平台)。
布尔型(Boolean Type)
bool:布尔型,表示真(true)或假(false)。

2. 复合类型

复合类型是由内置类型或其他复合类型组合而成的类型,主要包括以下几种:
数组(Array)
一组相同类型的数据元素,可以通过索引访问。
结构体(Struct)
一种用户定义的数据类型,可以包含不同类型的数据成员。
联合体(Union)
与结构体类似,但所有成员共享同一内存位置,只有一个成员可以在任何给定时间存储值。
枚举(Enum)
一种用户定义的类型,用于定义一组命名的整型常量。
类(Class)
C++的面向对象编程特性,允许定义包含数据和成员函数的复杂数据类型。
指针(Pointer)
指向其他类型的内存地址,可以用来动态分配内存和实现复杂的数据结构。
引用(Reference)
对现有变量的别名,提供了对变量的另一种访问方式。

注意:Std::string name =”xxxl”; 这不是字符类型,是字符串类型,属于复合类型,这是得益于std作用域下,定义了一个类,只要和这个类相关的,我们叫做类类型-->复合类型,String 里是包含char的

总的来说:判断是否为复合类型在于:是不是自己定义的类,c++大佬定义的,STL容器定义的类(比如 map,vector都是属于类的复合类型),其余的一般都是基本类型。

引用类型

定义:

C++ 中的引用类型是一种复合类型,它是对另一个变量的别名。在C++中使用引用,可以让我们直接访问和操作另一个变量的内存地址,而不需要通过指针的解引用操作。引用在语法上比指针更简洁,且在许多情况下更安全。

可能大家对上面文字理解太吃力,那我们试着想一下变量的存储:

可以看出:

定义一个变量a,并且初始化为100,编译器会为变量a开辟空间,绿色的是开辟的空间,存储100,这个空间的首地址为0x2be3,也就是变量a的地址。

地址大家可以裂解为门牌号,我们可以通过门牌号找到绿色的家,a是绿色的家的名字,进而取出家里的物品,数据100可以理解为物品。

执行b = a,将a赋值给b后,编译器又开辟了一块空间,存储100,这个空间的首地址为0x3f2b。 打个比方,我们又创建了一个家,家的名字是b,家里也存储了100这个物品,但是这个家的地址和a的不一样。

演示:

我们同样定义了一个变量a,并为它开辟空间,存储100,空间的首地址为0x2be3,我们定义了一个引用b,它是a的别名,所以b的地址和a的地址都一样,都是0x2be3

从上述图形可以看出,引用是变量的别名。

写法:

// 定义变量a
int a = 100;
// 定义引用b并且指向a, b就是a的别名
int &b = a;

这个 int & 表示的就是b是int类型的引用变量,如果你想查看a和b的地址是否真的相同,那我们可以这样写:

std::cout << "a的地址为:" << &a << std::endl;
std::cout << "b的地址为: " << &b << std::endl;

在a和b前加  即可输出他们的地址:

可以看到a和b的地址相同。也证明了a和b是指向同一个地址空间。所以我们修改a的值,b的值也会变

// 定义变量a
int a = 100;
// 定义引用b并且指向a, b就是a的别名
int &b = a;
// 输出a和b的值
std::cout << "a的值:" << a << std::endl;
std::cout << "b的值: " << b << std::endl;

// a和b是指向同一个变量。所以我们修改a的值,b的值也会变
a = 200;
std::cout << "修改a的值后,a和b的值分别为:\n" << a << std::endl;
std::cout << b << std::endl;

可以看到修改了a的值,b也跟着变化了,接下来我们修改b的值

// 修改b的值,a的值也会变
b = 300;
std::cout << "修改b的值后,a和b的值分别为:\n" << a << std::endl;
std::cout << b << std::endl;

程序输出:

可以看到b的值修改了,a的值也变化了

// 定义c,存储a的值
int c = a;
std::cout << "c的值:" << c << std::endl;
// 修改c的值
c = 400;
std::cout << "修改c的值后,c为:" << c << std::endl;
std::cout << "修改c的值后,a和b的值分别为:\n" << a << std::endl;
std::cout << b << std::endl;

可以看到c为a的副本,修改c不影响到a和b。

特性:

1.必须初始化:引用在创建时必须被初始化,它必须指向某个已存在的对象。

2.一旦绑定,不可改变:引用一旦被初始化后,它将一直保持与其初始对象的绑定,不能改变为另一个对象的引用。

3.没有空引用:引用必须指向某个对象,不能存在空引用(但会有空指针)

#include <iostream>
int main() {
    int a = 100;
    int &b = a; // b是a的引用
    std::cout << "a = " << a << ", b = " << b << std::endl; // 输出: a = 100, b = 100
    b = 200; // 更改b的值也会更改a的值
    std::cout << "a = " << a << ", b = " << b << std::endl; // 输出: a = 200, b = 200
    // int c = 300;
    // 表示修改b的值为c的值
    // b = c; 
    return 0;
}

注意事项:

引用主要用于函数参数和返回值,以及类的成员变量等场景,以提供对原始数据的直接访问,从而提高程序的效率和可读性。

引用可以是const的,这表示你不能通过引用来修改它所指向的对象的值。

引用在内部实现上通常是通过指针来实现的,但它们在语法和用途上与指针有显著的不同。引用提供了更直观、更安全的访问方式。

这里普及一下const是什么?

const=constant,只读,不可修改的,表示常量,作用:修饰变量/参数/函数/指针,声明它是只读,不能被赋值修改,编译器会检查防止误改

左值引用和右值引用

在C++中,左值(lvalue)和右值(rvalue)是表达式的两种基本分类,它们决定了表达式的结果在内存中的位置和状态。左值通常指的是具有持久状态的对象,它们有明确的内存地址,可以被多次赋值。而右值通常是临时的、没有持久状态的值,它们通常没有内存地址,或者其内存地址在表达式结束后就变得无效。

C++11引入了右值引用(rvalue reference),用T&&表示,作为对左值引用(lvalue reference,用T&表示)的补充。这一特性极大地增强了C++的表达能力,特别是在资源管理和性能方面。

左右值最大的区别就是:左值可以修改,右值是字面量,不能修改的(函数返回值,临时变量,字面量等),由此产生左值引用和右值引用。

左值引用

左值引用是C++98就有的特性,它允许我们为已存在的对象创建一个别名。左值引用必须被初始化为一个左值,即一个具有持久状态的对象。简单来说:绑定左值的引用

int a = 10;
int& b = a; // b是a的左值引用

右值引用

右值引用是C++11新增的特性,它允许我们为右值(即临时对象或即将被销毁的对象)创建一个引用。这样,我们就可以对右值进行更复杂的操作,比如移动语义(move semantics)。

int&& c = 20; // c是整数字面量20的右值引用(但这种情况不常见,通常用于函数参数或返回值)
std::string foo() {
    return std::string("Hello, World!"); // 返回的临时字符串是一个右值
}
std::string &&d = foo(); // d是foo()返回的临时字符串的右值引用

但请注意,直接绑定一个右值到右值引用(如int&& c = 20;)并不是右值引用的主要用途。右值引用的主要用途是作为函数参数(实现移动语义)和返回值(允许链式调用等)

移动语义和完美转发

右值引用的引入主要是为了支持移动语义(move semantics),它允许我们在对象被销毁前“窃取”其资源(如动态分配的内存、文件句柄等),而不是进行深拷贝。这可以显著提高性能,特别是在处理大型对象或容器时。

完美转发(perfect forwarding)是另一个与右值引用相关的概念,它允许我们将参数原封不动地传递给另一个函数,无论是左值还是右值。这通过模板和std::forward函数实现。

总结

左值引用(T&)是C++98就有的特性,用于为已存在的对象创建别名。

右值引用(T&&)是C++11新增的特性,用于为右值(即临时对象)创建引用,支持移动语义和完美转发等高级特性。

右值引用的主要用途不是直接绑定到字面量或简单的右值表达式上,而是在函数参数和返回值中,以实现更高效的资源管理和更灵活的代码编写方式。

结语:

快速掌握C++引用类型:从内置类型到复合类型详解!本文用生动比喻帮你理清左值引用、右值引用核心区别,学会移动语义提升代码性能,点击解锁引用初始化、绑定特性与实战技巧,让C++学习更高效

到此这篇关于C++引用类型全解析的文章就介绍到这了,更多相关C++引用类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解C++模板如何实现多态思想

    深入理解C++模板如何实现多态思想

    这篇文章主要为大家详细介绍了C++模板如何实现多态的相关资料,文中的示例代码讲解详细,对我们深入了解C++有一定的帮助,感兴趣的可以了解一下
    2023-03-03
  • C++中std::find函数介绍和使用场景

    C++中std::find函数介绍和使用场景

    std::find函数是一个非常实用的通用查找算法,适用于各种场景,本文主要介绍了C++中std::find函数介绍和使用场景,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • C++随机生成迷宫算法

    C++随机生成迷宫算法

    这篇文章主要为大家详细介绍了C++随机生成迷宫算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C++实现简单通讯录系统

    C++实现简单通讯录系统

    这篇文章主要为大家详细介绍了C++实现简单通讯录系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C语言文件操作详情(二)

    C语言文件操作详情(二)

    这篇文章主要介绍了C语言文件操作详情,文章基于上一篇文章的内容继续展开C语言文件操作的相关详情,需要的小伙伴可以参考一下
    2022-04-04
  • C++深入讲解类与对象之OOP面向对象编程与封装

    C++深入讲解类与对象之OOP面向对象编程与封装

    学习过C语言的小伙伴知道:C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题,接下来让我们详细的了解
    2022-05-05
  • C语言实现纸牌计算24点小游戏

    C语言实现纸牌计算24点小游戏

    这篇文章主要为大家详细介绍了C语言实现纸牌计算24点小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 浅谈C++性能榨汁机之伪共享

    浅谈C++性能榨汁机之伪共享

    使给定内存位置被一个线程所访问,可能还是会有乒乓缓存的存在,是因为另一种叫做伪共享(false sharing)的效应。即使数据存储在缓存行中,多个线程对数据中的成员进行访问时,硬件缓存还是会产生乒乓缓存。本文将介绍C++中的伪共享
    2021-06-06
  • C++ 取地址符相关的默认函数

    C++ 取地址符相关的默认函数

    本文主要介绍了C++ 取地址符相关的默认函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • 最新C/C++中的new和delete的实现过程小结

    最新C/C++中的new和delete的实现过程小结

    这篇文章主要介绍了C/C++中的new和delete的实现过程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论