c++中ref的作用示例解析

 更新时间:2023年04月23日 14:52:22   作者:泽林阿  
这篇文章主要为大家介绍了c++中ref的作用示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

C++11 中引入 std::ref 用于取某个变量的引用,这个引入是为了解决一些传参问题。

我们知道 C++ 中本来就有引用的存在,为何 C++11 中还要引入一个 std::ref 了?主要是考虑函数式编程(如 std::bind)在使用时,是对参数直接拷贝,而不是引用。下面通过例子说明

示例1:

#include <functional>
#include <iostream>
void f(int& n1, int& n2, const int& n3)
{
    std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
    ++n1; // increments the copy of n1 stored in the function object
    ++n2; // increments the main()'s n2
    // ++n3; // compile error
}

int main()
{
    int n1 = 1, n2 = 2, n3 = 3;
    std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3));
    n1 = 10;
    n2 = 11;
    n3 = 12;
    std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
    bound_f();
    std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
}

输出:

Before function: 10 11 12
In function: 1 11 12
After function: 10 12 12

上述代码在执行 std::bind 后,在函数 f() 中n1 的值仍然是 1,n2 和 n3 改成了修改的值,说明 std::bind 使用的是参数的拷贝而不是引用,因此必须显示利用 std::ref 来进行引用绑定。具体为什么 std::bind 不使用引用,可能确实有一些需求,使得 C++11 的设计者认为默认应该采用拷贝,如果使用者有需求,加上 std::ref 即可。

#include <thread>
#include <iostream>
#include <string>
void threadFunc(std::string &str, int a)
{
    str = "change by threadFunc";
    a = 13;
}

int main()
{
    std::string str("main");
    int a = 9;
    std::thread th(threadFunc, std::ref(str), a);

    th.join();

    std::cout<<"str = " << str << std::endl;
    std::cout<<"a = " << a << std::endl;

    return 0;
}

该程序创建一个线程 th,调用带有两个参数的 threadFunc 函数:一个是 std::string 对象 str 的引用,另一个是整数 a。函数 threadFunc 修改字符串 str 为 "change by threadFunc",但不修改整数 a。最后在主线程中输出 stra 的值。

输出:

str = change by threadFunc
a = 9

可以看到,和 std::bind 类似,多线程的 std::thread 也是必须显式通过 std::ref 来绑定引用进行传参,否则,形参的引用声明是无效的。

总结

std::ref 是一个 C++ 标准库函数模板,它将对象的引用转换为可复制的可调用对象。

std::ref 用于将对象的引用传递给函数或线程等可调用对象的参数。如果不使用 std::ref,那么函数或线程会将对象的副本传递给可调用对象的参数,这可能会导致无法预期的结果,因为对该副本的修改不会影响原始对象。通过使用 std::ref,可以确保可调用对象引用的是原始对象,因此对该对象的修改将影响原始对象。

需要注意的是,使用 std::ref 前必须确保原始对象的生命周期至少与可调用对象相同,否则会导致悬空引用。另外,std::ref 不能用于将指向临时对象或将过时对象的引用传递给可调用对象。

总之,std::ref 的作用是将对象的引用转换为可复制的可调用对象,使得在函数或线程等可调用对象中引用原始对象,而不是其副本。

以上就是c++中ref的作用示例解析的详细内容,更多关于c++ ref作用的资料请关注脚本之家其它相关文章!

相关文章

  • C语言数据结构与算法之链表(一)

    C语言数据结构与算法之链表(一)

    链表是线性表的链式存储方式。链表的内存是不连续的,前一个元素存储地址的下一个地址中存储的不一定是下一个元素。小编今天就将带大家深入了解一下链表,快来学习吧
    2021-12-12
  • Qt5 串口类QSerialPort的实现

    Qt5 串口类QSerialPort的实现

    在Qt5以上提供了QtSerialPort模块,方便编程人员快速的开发应用串口的应用程序。本文主要介绍了Qt5 串口类QSerialPort的实现,,感兴趣的可以了解一下
    2022-05-05
  • 位运算实现十进制转换为二进制

    位运算实现十进制转换为二进制

    这篇文章主要介绍了位运算实现十进制转换为二进制的相关资料,需要的朋友可以参考下
    2015-03-03
  • C语言结合ffmpeg打印音视频信息

    C语言结合ffmpeg打印音视频信息

    这篇文章主要介绍了如何通过C语言或者C++编程语言结合ffmpeg拿到一些音视频的关键信息,例如:帧率等。感兴趣的小伙伴可以跟随小编一起学习一下
    2021-12-12
  • VSCode (Visual Studio Code) V1.43.0下载并设置成中文语言的方法

    VSCode (Visual Studio Code) V1.43.0下载并设置成中文语言的方法

    Visual Studio Code是一款免费开源的现代化轻量级代码编辑器,支持语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性,这篇文章主要介绍了VSCode (Visual Studio Code) V1.43.0下载并设置成中文语言,需要的朋友可以参考下
    2020-03-03
  • C++通过boost.date_time进行时间运算

    C++通过boost.date_time进行时间运算

    这篇文章介绍了C++通过boost.date_time进行时间运算的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C++利用用埃式筛法求解素数

    C++利用用埃式筛法求解素数

    埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。本文将利用这一算法实现求解素数,感兴趣的可以了解一下
    2023-01-01
  • 在while中使用cin>>a 为条件及注意事项说明

    在while中使用cin>>a 为条件及注意事项说明

    这篇文章主要介绍了在while中使用cin>>a 为条件及注意事项说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C++实现区块链的源码

    C++实现区块链的源码

    这篇文章主要介绍了C++实现区块链的源码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 详解C语言快速排序三种方法的单趟实现

    详解C语言快速排序三种方法的单趟实现

    本文将通过图片重点为大家介绍一下C语言中快速排序三种方法的单趟实现:分别是hoare法、挖坑法、双指针法,文中示例代码讲解详细,感兴趣的可以了解一下
    2022-06-06

最新评论