我们可以使用移动语义在堆栈上移动堆分配的对象吗?
#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();
});
}
答案 0 :(得分:8)
std::move
不会重定位对象。它移动了价值。 (想想一些机器语言中的MOV R1, R2
指令:它不会移动寄存器,只移动内容!或memmove
库函数。这就是“移动”的感觉,而不是发生的那种移动在复制或压缩垃圾收集器时,这会导致对象驻留在不同的地址,同时保留其确切的标识,这包括在机器的任何位置查找移动对象的每一个引用并更新它。)
移动语义是C ++中的一个新功能,它允许以不必保留旧值的方式复制对象。这对于不再需要旧对象的情况很有用,因为它可以更快。
例如,将向量从一个std::vector<X>
移动到另一个可以使源对象成为零长度向量,并且所有数据都可以在没有任何内存分配或复制的情况下移动。由于这个想法是没有使用旧的向量,所以它已被破坏为零长度并不重要。
由于这些操作数之间的复制结构在C ++中一直运行良好,因此没有理由在不同存储位置(例如自由存储(“堆”)到自动存储(“堆栈”)之间不起作用。