Не понятно работающая логика удаления объекта

Рейтинг: 0Ответов: 1Опубликовано: 08.08.2023

Изучаю работу простого сервера на boos::asio. Один из примеров работы с ним я нашел тут: https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp Однако в примере мне не понятно поведение программы в функции void do_accept(), а именно в строке

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

Тут создается shared_ptr и у объекта вызывается метод start. После выхода из блока этот умный указатель должен быть уничтожен, однако этого не происходит. В чем причина?

Ответы

▲ 0

После выхода из блока этот умный указатель должен быть уничтожен, однако этого не происходит. В чем причина?

В start мы начинаем читать данные с сокета:

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

, и, если Вы посмотрите на обработчик (это лямбда-функция в примере выше), то увидите, что self передается в capture list лямба-функции - таким образом мы создаем копию текущего std::shared_ptr<Session>, соответственно, объект продолжает себе спокойно жить дальше.

P.S. Объект обработчика не хранится в _socket (хотя, по коду так может показаться).


Все равно не понятно. Объект самого умного указателя создается в do_connect. Откуда объект из do_read знает что в методе do_connect есть экземпляр?

В Вашем примере я вообще do_connect не вижу. do_read это член-функция session, внутри нее мы создаем копию текущего std::shared_ptr<session> и передаем ее в обработчик. Вы спрашиваете, "Откуда объект из do_read знает..." - так это один и тот же объект, мы у него и вызываем do_read.