std::move是否使指针无效



假设如下:

template<typename Item>
class Pipeline
{
    [...]
    void connect(OutputSide<Item> first, InputSide<Item> second)
    {
        Queue<Item> queue;
        first.setOutputQueue(&queue);
        second.setInputQueue(&queue);
        queues.push_back(std::move(queue));
    }
    [...]
    std::vector<Queue<Item> > queues;
};

移动后,指向队列的指针仍在"第一"one_answers"第二"中工作吗?

std::move是否使指针无效?

没有。一个对象在从中移出后仍然存在,因此指向该对象的任何指针仍然有效。如果Queue得到了合理的实现,那么从中移出应该会使其处于有效状态(即销毁或重新分配它是安全的);但可能会改变其状态(可能会使其变空)。

移动后,指向队列的指针仍在"第一"one_answers"第二"中工作吗?

没有。它们将指向已移动的本地对象;如上所述,您不能对移动后对象的状态做出任何假设。

更糟糕的是,当函数返回时,它会被破坏,留下指针。它们现在是无效的,不指向任何对象,使用它们将产生未定义的行为。

也许您希望它们指向已移动到queues:中的对象

queues.push_back(std::move(queue));
first.setOutputQueue(&queue.back());
second.setInputQueue(&queue.back());

但是,由于queues是一个向量,当队列下一次重新分配其内存时,这些指针将无效。

要解决此问题,请使用类似dequelist的容器,该容器在插入后不会移动其元素。或者,以额外的间接级别为代价,您可以存储(智能)指针而不是对象,正如Danvil的回答中所描述的那样。

指针将不起作用,因为queue是一个本地对象,将在connect结束时删除。即使使用std::move,您仍然可以在新的内存位置创建一个新对象。它将尝试使用尽可能多的"旧"对象。

此外,由于push_back可能需要重新分配,因此独立于使用std::move,整个事情根本无法工作。因此,对connect的调用可能会使所有旧指针失效。

一个可能的解决方案是在堆上创建Queue对象。以下建议使用C++11:

#include <memory>
template<typename Item>
class Pipeline
{
    [...]
    void connect(OutputSide<Item> first, InputSide<Item> second)
    {
        auto queue = std::make_shared<Queue<Item>>();
        first.setOutputQueue(queue);
        second.setInputQueue(queue);
        queues.push_back(queue);
    }
    [...]
    std::vector<std::shared_ptr<Queue<Item>>> queues;
};

其他人提供了很好的详细解释,但你的问题表明你不完全理解move的功能,也不完全理解它的设计目的。我会用简单的语言来描述它。

顾名思义,move的意思是移动东西。但是什么是可以移动的呢?一旦对象被分配到某个位置,就不能移动它。回想一下最近添加的新移动构造函数,它类似于复制构造函数。。

所以,这一切都是关于一个对象的"内容"。复制构造函数和移动构造函数都是对"内容"进行操作的。std::move也是如此。它意味着将一个对象的内容移动到目标中,与copy相比,它意味着在原始位置不留下任何内容痕迹。

它意味着在任何地方都可以使用,因为有东西迫使我们制作一个我们并不真正关心的副本,我们真的想省略它,并且只在目标位置有内容。

也就是说,使用"move"表示将制作副本内容将移动到那里并且原始内容将被清除(有时可能会跳过一些步骤,但这仍然是move的基本思想)。

这清楚地表明,即使原始内容仍然存在,指向原始对象的任何指针都不会指向接收内容的目标。充其量,他们会指向刚刚"清除"的原始内容。最坏的情况是,它会指向一个完全无法使用的东西。

现在看看你的代码。它填充queue,然后将指针指向原始指针,然后是movesqueue

我希望现在能清楚地知道发生了什么,以及你能做些什么。

最新更新