2016-05-04 3 views
1

Durch die Beispiele der Asio-Bibliothek, this one for example (zum Beispiel, Zeile 37), sehe ich, dass sie manchmal einen gemeinsamen Zeiger von diesem erstellen (sie selbst nennen), und nehmen Sie es in einem Lambda auf, wo sie einige Asio-Funktionen nennen, aber ich verstehe nicht, was der Zweck davon ist. Ich sehe es nicht einmal benutzt.Asio: Verwendung von selbst geteilten Zeiger in den Beispielen

Also, warum tun sie das?


Relevante Code:

..in der Serverklasse ... (wo eine Sitzung erstellt wird)

if (!ec) 
{ 
    std::make_shared<session>(std::move(socket_))->start(); 
} 

... session::start() Mitglied Methode:

void start() 
    { 
    do_read(); 
    } 

... session::do_read() Mitglied Methode (wo mein Punkt von Interesse ist): der dieser Zeiger) aus der Klasse Objekt

void do_read() 
    { 
    auto self(shared_from_this());     // <<< ---WHY THIS?????? 
    socket_.async_read_some(asio::buffer(data_, max_length), 
     [this, self](std::error_code ec, std::size_t length) 
     { 
      if (!ec) 
      { 
      do_write(length); 
      } 
     }); 
    } 

Antwort

3

Der Zweck std::enable_shared_from_this<> ist eine zusätzliches std::shared_ptr vom std::shared_ptr Griff zu erstellen, die das Objekt aufrufen shared_from_this Member-Funktion besitzt.


if (!ec) 
{ 
    std::make_shared<session>(std::move(socket_))->start(); 
} 

die oben - ^^^ - ist, wo die line, die eine session schafft. Und wie Sie sehen können, die std::shared_ptr, die von std::make_shared zurückgegeben wird am ; zerstört werden, was auch für die eigenen session zerstören soll ...

Aber weil start() Methode ruft do_read() die definiert ist als ...

void do_read() 
    { 
    auto self(shared_from_this()); 
    socket_.async_read_some(asio::buffer(data_, max_length), 
     [this, self](std::error_code ec, std::size_t length) 
     { 
      if (!ec) 
      { 
      do_write(length); 
      } 
     }); 
    } 

Das self erhöht die shared_ptr Referenzzahl. Die Zerstörung des original shared_ptr erstellt wird nicht das Objekt zerstören, sondern es wird sich selbst als Referenz auf das erstellte Objekt verlassen.


auch wissen, dass ein Lambda seine Anrufer überleben kann ... boost::asio::async_write ist eine asynchrone Methode, die sofort zurückkehrt, nachdem er die Argumente zu kopieren. Das übergebene Lambda wird möglicherweise nicht ausgeführt, bevor Sie das Ende der Lebensdauer Ihrer erreichen. Ohne die zusätzlichen std::shared_ptr erstellt von shared_from_this, wird der Destruktor ausgeführt.Das zusätzliche shared_ptr verhindert, dass der Destruktor von session ausgeführt wird, bis die Lambda-Funktion aufgerufen wird und die Argumente zerstört sind.

1

Das auf dem Lambda, die Sie Staat (zB aufnimmst und sie müssen das Objekt, um sicherzustellen, ist noch am Leben, wenn sie den Zustand zugreifen. Denken Sie daran, dass diese Lambdas asynchron aufgerufen werden, z. B. wenn Daten bereit zum Lesen sind. Die Funktion, die die Klasse anfänglich instanziierte, und die asynchronen Lambdas teilen somit alle das Eigentum der Klasseninstanz.

Haben Sie this gelesen, wenn nicht hilfreich?

Verwandte Themen