首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么使用std::move并赋值给rvalue不能窃取内部内容?

使用std::move并赋值给rvalue不能窃取内部内容的原因是因为std::move只是将对象的状态转移,而不会实际移动或复制对象的内部内容。

std::move是一个类型转换函数,它将一个左值转换为右值引用。右值引用表示一个临时对象或即将被销毁的对象,它可以被移动或窃取内部内容。但是,std::move本身并不会执行实际的移动操作,它只是将对象的状态标记为可移动。

当使用std::move将一个对象赋值给一个rvalue时,实际上只是将对象的状态转移给了新的变量,而不是移动或复制对象的内部内容。这意味着原始对象和新的变量仍然共享相同的内部内容,而不是窃取内部内容。

要实现真正的移动语义,需要使用移动构造函数或移动赋值运算符。移动构造函数和移动赋值运算符可以在对象之间传递内部内容的所有权,从而实现高效的资源管理和避免不必要的复制。

总结起来,使用std::move并赋值给rvalue不能窃取内部内容,因为std::move只是将对象的状态转移,而不会实际移动或复制对象的内部内容。要实现真正的移动语义,需要使用移动构造函数或移动赋值运算符。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

左值和右值、左值引用与右值引用、移动语句(2)「建议收藏」

术语rvalue右值指的是存储在存储器中某个地址的数据值。 rvalue是一个不能赋值的表达式。文字常量和变量都可以作为右值。当左值出现在需要右值的上下文中时,左值将隐式转换为右值。...它与纯右值在功能上及其相似,如都不能做操作符的左操作数,都可以使用移动构造函数和移动赋值运算符。当一个纯右值来完成移动构造或移动赋值任务时,其实它也具有“将亡”的特点。...另外,编译器永远不会自动生成move版本的构造函数和赋值函数,它们需要你手动显式地添加。 当添加了move版本的构造函数和赋值函数的重载形式后,某一个函数调用应当使用哪一个重载版本呢?...当构造函数或赋值函数传入一个非常量右值时,依据上面给出的判决规则,可以得出会调用move版本的构造函数或赋值函数。...而在move版本的构造函数或赋值函数内部,都是直接“移动”了其内部数据的指针(因为它是非常量右值,是一个临时对象,移动了其内部数据的指针不会导致任何问题,它马上就要被销毁了,我们只是重复利用了其内存),

2.6K20

C++11移动语义与右值引用

2.2 std::move 强制转化为右值引用 虽然不能直接对左值建立右值引用,但是我们可以显示地将一个左值转换为对应的右值引用类型。...move告诉编译器,在对一个左值建立右值引用后,除了对左值进行销毁和重新赋值不能够再访问它。...特别的,我们既可以传递左值,也可以传递右值std::move: string s1("hi"); string&& s2=std::move(string("bye")); //正确:从一个右值移动数据...(2)typename为什么会出现在std::move返回值前面?...同理,如果想以左值来调用移动构造函数构造容器Container的话,那么需要将左值对象通过std::move来获取对其的右值引用,参考如下代码: //紧接上面的main函数中的内容 Container<

1.1K20
  • C++11——对象移动与右值引用

    使用&&来获取右值引用。这里右值下个定义:只能出现在赋值运算符右边的表达式才是右值。相应的,能够出现在赋值运算符左边的表达式就是左值,注意,左值也可以出现在赋值运算符的右边。...move告诉编译器,在对一个左值建立右值引用后,除了对左值进行销毁和重新赋值不能够再访问它。...std::move的VC10.0版本的STL库定义如下: /* * @brief Convert a value to an rvalue....关于typename为什么会出现在std::move返回值前面的说明。...同理,如果想以左值来调用移动构造函数构造容器Container的话,那么需要将左值对象通过std::move来获取对其的右值引用,参考如下代码: //紧接上面的main函数中的内容 Container

    85920

    一文入魂:妈妈再也不用担心我不懂C++移动语义了!

    我们只需要知道,通过std::move函数,我们可以告知编译器,某个对象不再需要了,可以把它的数据转移其他需要的对象用。...&& rRef1{ val }; // Error,不能引用左值int&& rRef2{ std::move(val) }; // OK,引用使用std::move标记的对象 移动语义的实现需要用到右值引用...::move(A); // 使用移动赋值运算符将对象A赋值对象B 三、移动构造函数和移动赋值运算符                    的生成规则 在C++11之前,我们拥有4个特殊成员函数,即构造函数...五、使用移动语义时需要注意的其他内容 在最后一节,我们聊聊与移动语义相关的一些额外内容。...) noexcept : val{ std::move(rValue.val) } , str{ std::move(rValue.str) } {} // 编译器自动生成的移动赋值运算符类似这样

    1.2K20

    右值引⽤与移动语义

    左值和右值 在C++中,左值(lvalue)和右值(rvalue)是两种不同的表达式类型,它们的主要区别在于它们在内存中的状态和使用方式。...实践证明,使用右值引用来接收返回值则会收到空的内容。但是右值引用不是可以延长右值的生命周期吗,为什么还是内容被销毁。...移动构造函数与移动赋值操作符 定义 移动构造函数: 定义:移动构造函数接受一个右值引用作为参数,通过“窃取”资源来初始化对象。...移动赋值操作符: 定义:移动赋值操作符重载,允许将一个右值引用的对象赋值当前对象。 语法:ClassName& operator=(ClassName&& other) noexcept。...移动构造: my_string::string s4 = move(s1); 使用std::move,这将 s1 转换为右值引用,使得移动构造函数被调用。

    11710

    【Modern C++】深入理解左值、右值

    作为C/C++开发人员,在平时的项目开发过程中,或多或少的听过左值和右值的概念,甚至在编译器报错的时候,遇到过lvalue和rvalue等字样;甚至使用std::move(),但是不知道其含义。...,在后面的内容中,会对这几种类型进行详细讲解。...无论是C++11之前的拷贝,还是C++11的move,str在填充(拷贝或者move)s之后,将被销毁,而被销毁的这个值,就成为将亡值。...rvalue不能放在赋值或者组合赋值符号的左边,例如:3 = 5,3 += 5,这些表达式没有意义,也编译不过。 rvalue可以用来初始化const左值引用(见下文)。...++i的操作是对i加1后再赋值i,所以++i的结果是具名的,名称就是i,所以++i是左值 对于i++而言,先将i的值进行拷贝(此处假设拷贝到临时变量ii),然后再对i加1,最后返回ii(其实不存在的,

    90521

    【Modern C++】深入理解移动语义

    但是,对于开发人员来说,使用指针和引用不能概括所有的场景,也就是说仍然存在拷贝赋值等行为;对于编译器来说,而对于RVO、NRVO等编译器行为的优化需要满足特定的条件(具体可以参考文章编译器之返回值优化)...C++11新标准重新定义了lvalue和rvalue允许函数依照这两种不同的类型进行重载。...,那么,现在我们介绍下为什么要有右值引用呢?...转换为右值引用 使用move之后,就意味着两点: 原对象不再被使用,如果对其使用会造成不可预知的后果 所有权转移,资源的所有权被转移新的对象 使用 在某些情况下,编译器会尝试隐式移动,这意味着您不必使用...push_back(T&&)使用BigObj的移动构造函数将资源从参数移动到vector的内部BigObj对象中。而在C++11之前,上述代码则生成参数的拷贝,然后调用BigObj的拷贝构造函数。

    84510

    【译】理解C和C++中的左值和右值

    本文的前述内容讲述了左值和右值的主要区别,即左值可以被修改,而右值不能。但C++11对这个区别来了个大反转,它允许在一些特殊场合下对右值的引用,故可以修改它们。...注意——这里准确地展示了在赋值运算符=里发生了什么。但假如我们想将一个右值赋值v2: cout << "assigning rvalue......\n"; 尽管我只是v2赋值了一个刚构造的vector,这里展示了一个更通用的场景:临时的右值被构建被赋v2(这种场景是存在的,比如函数返回一个vector)。...【1】右值可以被显示地赋左值,应当使用左值的地方,右值不能被隐式地转换。 【2】C++11标准section 4.1。 【3】谷歌搜索“右值引用”可以发现很多相关主题的文章。...【5】现在你们知道为什么我坚持把operator= 称作拷贝赋值运算符。在C++11里,这个区别尤其重要。

    1.2K10

    理解 C++ 右值引用和 std::move

    ** std::move 可以理解为把一个左值临时性地 cast 成右值 */ void func_rvalue_ref() { int tmp =10; A().init(std...std::vector v2; // 返回的vector被复制对象v2(拷贝复制运算符),需要先清理v2原数据,将临时对象数据复制v2,然后析构临时对象, v2...std::vector v2; // 返回的vector被移动对象v2,移动赋值运算符,先释放v2原有数据,然后直接从返回值取走数据,然后返回值被析构。.../复制的概念,但为了实现对资源的移动操作,调用者必须使用先复制、再析构的方式。...回到原题 为什么需要右值引用? 右值引用其实就为匿名(天生匿名或者通过 std::move 将名字失效,这样的对象即将被析构)对象重新起名字。

    83430

    C++11-右值引用新的类功能可变参数列表

    int&& r3=move(a); return 0; } 注意: 右值引用只能引用右值,不能引用左值 右值引用可以进行引用move以后的左值,move表示将该变量识别为右值 右值引用本质上是将引用的右值内容存储到空间中...,占位已有,那么就不 用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己,也就是说资源的生命周期被延长了(对象的生命周期不会改变) 移动赋值: 除了移动构造之外,还有移动赋值 Person...t的原生类型属性 Fun(std::forward(t)); } int main() { PerfectForward(10); // rvalue ref int a; PerfectForward...(a); // lvalue ref PerfectForward(std::move(a)); // rvalue ref const int b = 8; PerfectForward(b);...// const lvalue ref PerfectForward(std::move(b)); // const rvalue ref return 0; } 效果: 7、右值引用作用 C+

    84130

    CC++开发基础——移动语义和右值引用

    40:整型字面量,是个临时值,右值变量,不能被获取地址,编码时不能写&40。 二,右值引用的基本概念 右值引用,其实就是字面上说的,针对右值变量的引用。...针对对象的移动语义需要有: 1.移动构造函数 2.移动赋值运算符 移动构造函数和移动赋值运算符的参数都是右值引用"&&"类型。 C++标准库提供了移动语义相关的函数接口:std::move()。...std::move()的处理方式类似于强制类型转换,它可以将左值转换为右值。...C++标准库提供了用于完美转发的函数接口:std::forward()。 完美转发不改变变量的左右值属性,如果变量是左值,传入std::forward处理后该变量还是左值。...PerfectForward(std::move(d)); return 0; } 运行结果: lvalue ref. rvalue ref. const lvalue ref. const

    16410

    谈一谈 C++ 中的值的类型

    具体地说,就是可以移动构造,还有移动赋值。 移动语义有点像“废物利用”一样。如果采用了移动构造,你就可以把自己身上的数据移动新的成员,避免了不必要的数据复制。...比如要移动几千个 std::string 类型的成员,C++98 中只能够复制一份再删除一份,而 C++11 中,就可以改一下 std::string 内部指针的位置,很方便。...比如 std::move(x) 强制转换了右值引用 也就是说,通过使用 std::move(x) 就可以把 x 的类型变成 xvalue,就可以调用移动构造函数了(如果实现了这个函数)。...(小提示:不要写出 return std::move(x); 这种语句,写 return x; 就行,不然会妨碍编译器优化。...参考这里) ---- 进一步,我们可以抽象出来这两个判断法则: 准则 1:能不能分辨两个表达式指的是同一个物体。比如我们可以通过比较地址。 准则 2:能不能使用移动语义。

    63430

    左值、左值引用,右值,右值引用

    1是右值,不能使用左值引用 3、右值引用,c++11中的右值引用使用的符号是&&,如: int&& a = 1; //实质上就是将不具名(匿名)变量取了个别名 int b = 1; int && c...不能将一个左值复制一个右值引用 class A {   public:     int a; }; A getTemp() {     return A(); } A && a = getTemp()...Otherwise, it is an rvalue. 4、移动构造函数 在c++11 之前,类包括构造函数,析构函数,拷贝构造函数,赋值构造函数。...6、std::movestd::forward的区别: std::move执行一个无条件的转化到右值。...它本身并不移动任何东西; std::forward把其参数转换为右值,仅仅在那个参数被绑定到一个右值时; std::movestd::forward在运行时(runtime)都不做任何事。

    78710
    领券