了解共享指针的问题(生命周期,作为参数传递)

2024-04-22

我尝试从 boost asio 聊天示例开始并派生出一个自己的网络程序。不幸的是,我在理解到底发生了什么方面遇到了一些问题。我试图将我的程序减少到绝对最低限度。服务器类等待传入连接并创建会话对象来处理连接。这是服务器的代码:

#include <cstdint>
#include <iostream>
#include <sstream>
#include <memory>
#include <vector>

#include <boost/asio.hpp>
#include <boost/bind.hpp>

class Session : public std::enable_shared_from_this<Session>
{
public:
    Session(boost::asio::ip::tcp::socket __oSocket);
    virtual ~Session();
    void StartSession();
private:
    void StartRecv();
    std::vector<int32_t> m_vecSetupReceiveBuffer;
    boost::asio::ip::tcp::socket m_oSocket;
};

Session::Session(boost::asio::ip::tcp::socket __oSocket) :
    m_vecSetupReceiveBuffer({2}),
    m_oSocket(std::move(__oSocket))
{    }

Session::~Session()
{
    std::cout << "Deleted session" << std::endl;
}

void Session::StartSession()
{
    auto self(shared_from_this());
    std::cout << "StartSession()" << std::endl;
    boost::asio::async_write(m_oSocket, boost::asio::buffer(m_vecSetupReceiveBuffer),
    [this, self](boost::system::error_code _oError, std::size_t)
    {
        std::cout << m_vecSetupReceiveBuffer.size() << std::endl;
        StartRecv();
    });
}

void Session::StartRecv()
{
    auto self(shared_from_this());
    std::cout << "StartRecv()" << std::endl;
    boost::asio::async_read(m_oSocket, boost::asio::buffer(m_vecSetupReceiveBuffer),
    [this, self](boost::system::error_code _oError, std::size_t)
    {});
}

class Server
{
public:
    Server(boost::asio::io_service& _rIOService, uint32_t _nPort);
    virtual ~Server();
private:
    void StartAccept();
    boost::asio::ip::tcp::acceptor m_oAcceptor;
    boost::asio::ip::tcp::socket m_oSocket;
};

Server::Server(boost::asio::io_service& _rIOService, uint32_t _nPort) :
    m_oAcceptor(_rIOService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), _nPort)),
    m_oSocket(_rIOService)
{
    StartAccept();
}

Server::~Server()
{}

void Server::StartAccept()
{
    m_oAcceptor.async_accept(m_oSocket,
    [this](boost::system::error_code _oError)
    {
        std::make_shared<Session>(std::move(m_oSocket))->StartSession();
        StartAccept();
    });
}


int main(int argc, char* argv[])
{
    boost::asio::io_service _oIOServerService;
    std::shared_ptr<Server> _pServer(std::make_shared<Server>(_oIOServerService, 2000));
    _oIOServerService.run();
    return 0;
}

这段代码按预期运行,但是当我尝试调整一些东西并进行一些操作时,我发现我不明白共享指针何时真正创建和删除以及它们存储在哪里。例如我试图改变std::make_shared<Session>(std::move(m_oSocket))->StartSession(); to std::make_shared<Session>(std::move(m_oSocket));并添加了StartSession();在 Session 类的构造函数中。如果我运行代码,它会抛出

terminate called after throwing an instance of 'std::bad_weak_ptr'
what():  bad_weak_ptr
Aborted (core dumped)

这大概发生在auto self(shared_from_this());。但我不明白为什么?我应该在我的代码中更改什么?所以我认为我的问题是我不明白如何正确使用shared_ptr,如何在这些构造中使用它,我可以在哪里访问它以及如何使其可访问。此外,尚不清楚为什么我有时必须使用this以及何时使用shared_from_this()。有没有好的教程或简单的经验法则?

我也不清楚为什么有些人使用 lambda 函数表示法,而有些人则使用boost::bind记法和有什么区别?

所以请原谅我的新手问题,我试图在教程中找到一些信息,但我只是对这些共享指针和 boost::asio 感到困惑。似乎总是做一些奇怪的事情。


You get std::bad_weak_ptr因为没有shared_ptr owning this在你的建设过程中Session。你还在身体里make_shared,并且它还没有完成创建shared_ptr.

shared_from_this()只能从以下实例获得Session,它是一个成员函数。你通过派生继承了它std::enable_shared_from_this.

lambda 是用以下副本构造的self,以及成员Session就好像可用this还指出Session对象,而不是 lambda 对象,因为this capture

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解共享指针的问题(生命周期,作为参数传递) 的相关文章

随机推荐