堆分配的对象可以在堆栈上移动吗?

时间:2012-04-20 02:16:28

标签: c++ memory-management c++11 boost-asio move-semantics

问题

我们可以使用移动语义在堆栈上移动堆分配的对象吗?

实施例

#include <boost/asio.hpp>
#include <memory>

class connection
{
public:
    connection(boost::asio::ip::tcp::socket&& socket);

    void start();

private:
    boost::asio::ip::tcp::socket m_socket;
};

class server
{
public:
    // Not relevent here

private:
    void accept();

    boost::asio::io_service        m_io_service;
    boost::asio::ip::tcp::acceptor m_acceptor;
};

void server::accept()
{
    auto socket = new boost::asio::ip::tcp::socket(m_io_service);

    m_acceptor.async_accept(*m_socket,
    [&, socket](const boost::system::error_code& error)
    {
        if (!error)
        {
            auto connection = std::make_shared<connection>(std::move(*socket));
            connection->start();
        }

        accept();
    });
}

1 个答案:

答案 0 :(得分:8)

std::move不会重定位对象。它移动了价值。 (想想一些机器语言中的MOV R1, R2指令:它不会移动寄存器,只移动内容!或memmove库函数。这就是“移动”的感觉,而不是发生的那种移动在复制或压缩垃圾收集器时,这会导致对象驻留在不同的地址,同时保留其确切的标识,这包括在机器的任何位置查找移动对象的每一个引用并更新它。)

移动语义是C ++中的一个新功能,它允许以不必保留旧值的方式复制对象。这对于不再需要旧对象的情况很有用,因为它可以更快。

例如,将向量从一个std::vector<X>移动到另一个可以使源对象成为零长度向量,并且所有数据都可以在没有任何内存分配或复制的情况下移动。由于这个想法是没有使用旧的向量,所以它已被破坏为零长度并不重要。

由于这些操作数之间的复制结构在C ++中一直运行良好,因此没有理由在不同存储位置(例如自由存储(“堆”)到自动存储(“堆栈”)之间不起作用。