C++ Primer阅读笔记--对象移动(右值引用、移动迭代器和引用限定符的使用)

这篇具有很好参考价值的文章主要介绍了C++ Primer阅读笔记--对象移动(右值引用、移动迭代器和引用限定符的使用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1--右值引用

2--std::move

3--移动构造函数

4--移动赋值运算符

5--移动迭代器

6--引用限定符


1--右值引用

        右值引用必须绑定到右值的引用,通过 && 获得右值引用;

        右值引用只能绑定到临时对象(即将被销毁的对象),即所引用的对象将要被销毁,对象没有其他用户;

        返回非引用类型的函数,连同算术、关系、位已经后置递增/递减运算符,都生成右值;

int i = 42;
int &r1 = i; // 左值引用,i是一个变量,是左值
int &&r2 = i * 42; // 右值引用,i*42是一个临时对象,是右值 

2--std::move

        std::move 用于获得绑定到左值上的右值引用,其定义在头文件 utility 中;

int &&r1 = 42; // 右值引用,但r1是一个左值
int &&r2 = std::move(r1); // 调用std::move,调用后只能对r1进行赋值或销毁,不能再使用

3--移动构造函数

        移动构造函数的第一个参数是该类类型的一个右值引用

        移动构造函数必须确保移动后,销毁源对象是无害的;

        移动构造函数不分配任何新内存,只是接管给定的内存;

A::A(A &&s) noexcept : data1(s.data1), data2(s.data2), data3(s.data3){
    s.data1 = s.data2 = s.data3 = nullptr;
}
// 假定data1,data2 和 data3 均是指针
// noexcept 的作用是通过标准库对于上述构造函数不抛出任何异常
// 在移动构造函数的函数体中,对源对象的指针数据进行赋值,可以避免由于源对象析构导致释放刚刚移动的内存的问题

4--移动赋值运算符

A &A::operator=(A &&sample) noexcept{
    if(this != &sample){
        data1 = sample.data1;
        data2 = sample.data2;
        data3 = sample.data3;
        sample.data1 = sample.data2 = sample.data3 = nullptr;
    }
    return *this;
}

5--移动迭代器

        移动迭代器的解引用运算符生成一个右值引用,通过调用标准库的 make_move_iterator 函数可以将一个普通迭代器转换为一个移动迭代器;

        移动一个对象可能会销毁原对象,当确信一个算法为一个元素赋值或传递给函数后不会再访问原对象,才能使用移动迭代器将对象传递给算法;

#include <iostream>     
#include <iterator>          
#include <string>       
#include <vector>

int main (int argc, char *argv[]){
   std::vector<std::string> foo (3);
   std::vector<std::string> bar {"A", "B", "C"};
   typedef std::vector<std::string>::iterator Iter;
   std::copy ( std::move_iterator<Iter>(bar.begin()), // 使用移动迭代器
               std::move_iterator<Iter>(bar.end()),
               foo.begin() );
   bar.clear(); // 移动 bar 后,清理
   std::cout << "foo:";
   for (std::string& x : foo) std::cout << ' ' << x;
   std::cout << std::endl;;
   return 0;
}

6--引用限定符

        右值没有内存实体,一般不能对其进行调用成员函数或赋值,但有时会出现以下情况:即右值调用成员函数或对右值进行赋值;

string s1 = "abc", s2 = "def";
auto n = (s1 + s2).find('a'); //(s1 + s2)是一个右值,对右值调用成员函数
s1 + s2 = "wc"; //(s1+s2)是一个右值,对右值赋值

        上述代码其实是没意义的,但 C++11 仍然保留了这种右值赋值或调用成员函数的机制;通过使用引用限定符可以显式阻止函数被左值或右值调用:文章来源地址https://www.toymoban.com/news/detail-686130.html

class demo{
	 int get_num();   // 默认情况下,成员函数既可以被左值或右值对象调用
	 int get_num()& ;  // &显式限制成员函数必须被左值成员对象调用
	 int get_num()&& ;  //&&显式限制成员函数必须被右值成员对象调用
}

class A{
	   A& operator=(const A&);
	   A& operator=(const A&) &;
	   A& operator=(const A&) &&;
}

到了这里,关于C++ Primer阅读笔记--对象移动(右值引用、移动迭代器和引用限定符的使用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【重学C++】05 | 说透右值引用、移动语义、完美转发(下)

    【重学C++】05 | 说透右值引用、移动语义、完美转发(下) 大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第五讲,在第四讲《【重学C++】04 | 说透右值引用、移动语义、完美转发(上)》中,我们解释了右值和右值引用的相关概念,并介绍了C++的移动语义以及如

    2024年02月06日
    浏览(32)
  • C++右值引用(左值表达式、右值表达式)(移动语义、完美转发(右值引用+std::forward))(有问题悬而未决)

    在 C++ 中,表达式可以分为左值表达式和右值表达式。左值表达式指的是可以出现在赋值语句左边的表达式,例如变量、数组元素、结构体成员等;右值表达式指的是不能出现在赋值语句左边的表达式,例如常量、临时对象、函数返回值等。 右值是指将要被销毁的临时对象或

    2024年02月04日
    浏览(33)
  • 【C++干货铺】C++11新特性——右值引用、移动构造、完美转发

    ========================================================================= 个人主页点击直达:小白不是程序媛 C++系列专栏:C++干货铺 代码仓库:Gitee ========================================================================= 目录 左值与左值引用 右值与右值引用 左值引用和右值引用的比较  左值引用总结:

    2024年01月25日
    浏览(30)
  • 【C++】 C++11(右值引用,移动语义,bind,包装器,lambda,线程库)

    C++11是C++语言的一次重大更新版本,于2011年发布,它包含了一些非常有用的新特性,为开发人员提供了更好的编程工具和更好的编程体验,使得编写高效、可维护、安全的代码更加容易。 一些C++11的新增特性包括: 强制类型枚举,使得枚举类型的通常行为更加可靠和容易控制

    2024年02月10日
    浏览(34)
  • C++标准库 -- 顺序容器 (Primer C++ 第五版 · 阅读笔记)

    所有容器类都共享公共的接口,不同容器按不同方式对其进行扩展。 这个公共接口使容器的学习更加容易—我们基于某种容器所学习的内容也都适用于其他容器。 每种容器都提供了不同的性能和功能的权衡。 下表列出了标准库中的顺序容器, 所有顺序容器都提供了 快速顺序

    2023年04月17日
    浏览(76)
  • C++标准库 -- 泛型算法 (Primer C++ 第五版 · 阅读笔记)

    顺序容器只定义了很少的操作:在多数情况下,我们可以添加和删除元素访问首尾元素、确定容器是否为空以及获得指向首元素或尾元素之后位置的迭代器。 我们可以想象用户可能还希望做其他很多有用的操作:查找特定元素、替换或删除一个特定值、重排元素顺序等。 标准库

    2023年04月21日
    浏览(35)
  • C++ Primer 5th 阅读笔记:变量和基本类型

    内建类型 ,如整型,字符型等; 变量 ,为值绑定的一个名字; 表达式和语句 ,操作值。 分支和循环 ,允许我们条件执行和重复执行; 函数 ,定义抽象计算单元。 自定义类型; 标准库。 学习语言的基本知识和标准库。 内建类型; 简要介绍自定义类。 定义了数据的意义

    2024年02月02日
    浏览(44)
  • C++右值引用,右值引用与const引用的区别

    左值:可以取地址的、有名字的变量,有持久性; 右值:一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。 C++11新增了另一种引用——右值引用。这种引用可指向右值,使用声明。 右值引用只能引用临时变量和常量值。 const引用:可以引用普

    2024年01月18日
    浏览(52)
  • 详解 C++ 左值、右值、左值引用以及右值引用

    左值是一个表示数据的表达式,比如: 变量名、解引用的指针变量 。一般地,我们可以 获取它的地址 和 对它赋值 ,但被 const 修饰后的左值,不能给它赋值,但是仍然可以取它的地址。 总体而言,可以取地址的对象就是左值。 右值也是一个表示数据的表达式,比如: 字面

    2023年04月08日
    浏览(37)
  • 【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发

    { } 初始化 C++11 扩大了括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义类型, 使用初始化列表,可添加等号(=),也可不添加 将1赋值给x1,x2处省略了赋值符号,将5赋值给x2 同样也可以将new开辟4个int的空间初始化为0 创建对象时,可以使用列

    2024年02月08日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包