LoginSignup
3
2

More than 5 years have passed since last update.

【boost::asio buffers】shared_ptrを使うとメモリ管理が楽になる for C++03

Posted at

今回のお題

boost1_57_0 buffers(C++03)
http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/example/cpp03/buffers/reference_counted.cpp

上記サンプルを CMakeプロジェクトにしたものを
下記リポジトリに置いておきます
https://github.com/MurasameOpen/CPPSample/tree/master/boostSample/boost1_57_0/asio/cpp03/buffers

解析

動作

C++11版と同じく 待ち受けポートをパラメータに 起動し
接続が来たら 現在時刻を返す

一応 telnetで接続してみましょう

telnet
miyatake_y$ telnet -4 localhost 8080 
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Wed Mar 25 01:29:25 2015
Connection closed by foreign host.

ソース解析

基本的に C++11のサンプルと同じですが
shared_ptr、bind等が 言語仕様に取り込まれていないので
boost:: の名前空間を使っていたり文法が多少違いますが
考え方はだいたい同じです

ソース

server

class server
{
public:
  server(boost::asio::io_service& io_service, short port)
    : io_service_(io_service),
      acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
  {
    session_ptr new_session(new session(io_service_));
    acceptor_.async_accept(new_session->socket(),
        boost::bind(&server::handle_accept, this, new_session,
          boost::asio::placeholders::error));
  }

  void handle_accept(session_ptr new_session,
      const boost::system::error_code& error)
  {
    if (!error)
    {
      new_session->start();
    }

    new_session.reset(new session(io_service_));
    acceptor_.async_accept(new_session->socket(),
        boost::bind(&server::handle_accept, this, new_session,
          boost::asio::placeholders::error));
  }

private:
  boost::asio::io_service& io_service_;
  tcp::acceptor acceptor_;
};

C++11では ラムダを使って make_sharedでコールバック関数を作成していたのが
boost::bindになり少し記述が増えました
が、やってる事は同じで、shared_ptrで sessionを作成し、startを呼びます

session
class session
  : public boost::enable_shared_from_this<session>
{
public:
  session(boost::asio::io_service& io_service)
    : socket_(io_service)
  {
  }

  tcp::socket& socket()
  {
    return socket_;
  }

  void start()
  {
    using namespace std; // For time_t, time and ctime.
    time_t now = time(0);
    shared_const_buffer buffer(ctime(&now));
    boost::asio::async_write(socket_, buffer,
        boost::bind(&session::handle_write, shared_from_this()));
  }

  void handle_write()
  {
  }

private:
  // The socket used to communicate with the client.
  tcp::socket socket_;
};

start() で async_write時に
C++11では ラムダ式で shared_from_this()をキャプチャさせ
自分のshared_ptrをキープしてましたが
ここでは boost::bindでキープに変わりましたが
基本は同じです

結論

非同期関数はメモリの管理が少し面倒
C++11ではラムダ式のキャプチャでshared_ptrをキープしていたが
C++03では boost::bindを使うと良さそうだ
C++11の方が、かなりコードが見通しが良くなる

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2