2017-10-13 148 views
2

捕獲此和shared_from_this()在升壓async-tcp-echo-server例子有一個服務器類上一個新的連接創建會話:升壓回聲服務器實例和拉姆達

acceptor.async_accept(socket, [this](boost::system::error_code ec) { 
    if (!ec) 
     std::make_shared<session>(std::move(socket))->start(); 
    do_accept(); 
}); 

session::start()功能體:

void start() { do_read(); } 

session::do_read方法是私人會員功能:

void do_read() 
{ 
    auto self(shared_from_this()); 
    socket.async_read_some(boost::asio::buffer(data, sizeof(data)), 
     [this, self](boost::system::error_code ec, std::size_t length) { 
      if (!ec) 
       do_write(length); 
    }); 
} 

請糾正我,如果我錯了。
會話類繼承自std::enable_shared_from_this,因此在調用shared_from_this()時已創建控制塊,並且不會發生未定義的行爲。在do_read功能shared_from_this()函數用於允許do_write()方法在內存中仍然存在的對象上調用。如果不使用shared_from_this(),則在達到範圍結束時可以刪除該對象。

爲什麼在lambda表達式中捕獲this
do_write()方法調用thisself

在C++ 14我能代替:

auto self(shared_from_this()); 
socket.async_read_some(boost::asio::buffer(data, sizeof(data)), 
    [this, self] ... 

有:

socket.async_read_some(boost::asio::buffer(data, sizeof(data)), 
     [this, shared_from_this()] ... 

? 或甚至以此:

socket.async_read_some(boost::asio::buffer(data, sizeof(data)), 
    [self = shared_from_this()](boost::system::error_code ec, std::size_t length) { 
     if (!ec) 
      self->do_write(length); 
}); 

回答

4

self對象被捕獲到lambda中作爲所有權令牌:只要lambda生存,令牌就會生存,並且對象不會被銷燬。

捕獲this是多餘這裏,但沒有它,一個會寫

if (!ec) 
    self->do_write(length); 

,而不是

if (!ec) 
    do_write(length); 

這是一樣的

if (!ec) 
    this->do_write(length); 

因此,this是主要爲了可讀性而捕獲。