C++11 对象在移动操作之前已销毁

C++11 对象在移动操作之前已销毁,c++11,C++11,我有点困惑,怎么可能破坏临时对象,然后将其移动到第二个。这是一种未定义的行为吗?是否缺少有关移动操作的信息?是的,此功能 constructing it 1 constructing it 2 destroying it 2 Moving it assignment 1 destroying it 1 它坏了 r值引用仍然是引用,在这种情况下,它是对本地堆栈对象的引用,该对象在函数终止时(从中移动之前)被销毁。相反,您应该只按值返回它,它仍然会被移出,如果有复制省略,那么它将是有效的。是的,此

我有点困惑,怎么可能破坏临时对象,然后将其移动到第二个。这是一种未定义的行为吗?是否缺少有关移动操作的信息?

是的,此功能

constructing it 1
constructing it 2
destroying it 2
Moving it assignment 1
destroying it 1
它坏了

r值引用仍然是引用,在这种情况下,它是对本地堆栈对象的引用,该对象在函数终止时(从中移动之前)被销毁。相反,您应该只按值返回它,它仍然会被移出,如果有复制省略,那么它将是有效的。

是的,此函数

constructing it 1
constructing it 2
destroying it 2
Moving it assignment 1
destroying it 1
它坏了

r值引用仍然是引用,在这种情况下,它是对本地堆栈对象的引用,该对象在函数终止时(从中移动之前)被销毁。相反,您应该只按值返回它,它仍然会被移出,如果存在复制省略,那么它将是有效的。

请看以下代码段:

Movable&& CreatenNewMovable ()
{
    Movable lM;
    return std::move(lM);
}
实际上,这是未定义的行为。有两个问题:

  • 函数只能通过值(可能是参考值)返回其值。因此,您必须在此处将
    Movable&
    替换为
    Movable
  • 创建<代码>可移动lM并在函数外部引用它是UB。当函数退出时,对象不再存在。简单地按值返回-在您的情况下,副本省略将生效
  • 最后,一个有效的方法是:

    Movable&& CreatenNewMovable ()
    {
        Movable lM;
        return std::move(lM);
    }
    
    这将产生您正在等待的结果:

    Movable CreatenNewMovable ()
    {
        Movable lM;
        return lM;
        // ..or..
        // Even better to return like this(copy elision has less chances to fail)
        // return Movable();
    }
    
    您甚至可以通过删除
    main
    中的空对象创建来减少此作业:

    $ ./w 
    constructing it 1
    constructing it 2
    Moving it assignment 1
    destroying it 2
    destroying it 1
    
    请看这个片段:

    Movable&& CreatenNewMovable ()
    {
        Movable lM;
        return std::move(lM);
    }
    
    实际上,这是未定义的行为。有两个问题:

  • 函数只能通过值(可能是参考值)返回其值。因此,您必须在此处将
    Movable&
    替换为
    Movable
  • 创建<代码>可移动lM并在函数外部引用它是UB。当函数退出时,对象不再存在。简单地按值返回-在您的情况下,副本省略将生效
  • 最后,一个有效的方法是:

    Movable&& CreatenNewMovable ()
    {
        Movable lM;
        return std::move(lM);
    }
    
    这将产生您正在等待的结果:

    Movable CreatenNewMovable ()
    {
        Movable lM;
        return lM;
        // ..or..
        // Even better to return like this(copy elision has less chances to fail)
        // return Movable();
    }
    
    您甚至可以通过删除
    main
    中的空对象创建来减少此作业:

    $ ./w 
    constructing it 1
    constructing it 2
    Moving it assignment 1
    destroying it 2
    destroying it 1
    

    我更改了函数Movable CreatenNewMovable(){Movable lM;return lM;}输出现在正在构造它1构造它2移动它赋值1销毁它2销毁它1。这意味着物体被移动然后被破坏。这与复制操作有何不同?对于所讨论的类,只有在移动比复制更有效的情况下才会有所不同。例如,在std::vector的情况下,移动操作的效率更高,因为它不分配新内存,也不复制或移动所有成员对象——移动的工作方式是“窃取”被移动对象所拥有的指针。您可能想看看这里:这里:我更改了函数Movable CreatenNewMovable(){可移动lM;返回lM;}输出现在正在构造它1构造它2移动它分配1销毁它2销毁它1。这意味着对象被移动然后被销毁。这与复制操作有什么不同?对于所讨论的类,只有当移动比复制更有效时才不同。例如,在std::vec的情况下tor,移动操作的效率更高,因为它不分配新内存,也不复制或移动所有成员对象——移动的工作原理是“窃取”被移动对象所拥有的指针。您可能想看这里:和这里: