在基类中使用shared_from_this时获取bad_weak_ptr

时间:2016-12-13 01:57:49

标签: c++ inheritance smart-pointers

我是C ++的新手并试图了解如何在我的情况下正确使用shared_from_this。

我有一个客户端连接类和服务器连接类都从Base连接类继承。基类方法处理它收到的所有消息(节点可以是客户端或服务器)。

我有一个ConnMgr类负责启动和处理新连接。当客户端节点启动连接时,我正在分配ClientConn shared_ptr对象,当服务器收到连接时,我正在创建ServerConn shared_ptr对象并将其分配给ConnMgr类中的tcp_conn_,这是socket_addr和BaseConn shared_ptr的映射。

建立连接后,为了处理消息,我需要生成“this”shared_ptr的实例。当我尝试使用shared_from_this()时,它会抛出bad_weak_ptr异常。 我明白了:

  • Base shared_ptr和Derived shared_ptr不是协变的。
  • 此外,enable_shared_from_this期望在调用shared_from_this()时获取shared_ptr。

在我的情况下,shared_ptr被创建为ClientConn或ServerConn,我在基类方法中没有任何想法。我也尝试过它,但它没有帮助。那么,我该如何解决这个问题?

回溯的片段:

__ gnu_cxx3__712_Lock_policyE2EE15_M_add_ref_lockEv __gnu_cxx3__712_Lock_policyE2EEC1ERKNS_12__weak_countILS3_2EEE __gnu_cxx3__712_Lock_policyE2EEC2IS1_EERKNS_10__weak_ptrIT_LS4_2EEE

class BaseConn : public std::enable_shared_from_this<BaseConn>
{
    void process_received_message()
    {
        std::shared_ptr<BaseConn> shared_this = shared_from_this();
    }
}

class ClientConn : public BaseConn
{
}

class ServerConn : public BaseConn
{
}

class ConnMgr
{
private:
    //there can be more than one connections. Hence using map.
    typedef std:map<socket_addr, std::shared_ptr<BaseConn>> tcp_conn_t;
    tcp_conn_t tcp_conn_;

public:
    void start_connection()
    {
        tcp_conn_[0] = std::make_shared<ClientConn>();
    }

    void handle_new_connection()
    {
        tcp_conn_[0] = std::make_shared<ServerConn>();
    }        
}

我也试过这样做,它没有帮助:

class BaseConn
{
public:
    void process_received_message()
    {
        std::shared_ptr<BaseConn> shared_this = get_shared_ptr();
    }

    virtual std::shared_ptr<BaseConn> get_shared_ptr() = 0;
}

class ClientConn : public std::enable_shared_from_this<ClientConn>
{
public:
    std::shared_ptr<BaseConn> get_shared_ptr()
    {
        return std::static_pointer_cast<BaseConn>(shared_from_this());
    }
}

class ServerConn : public std::enable_shared_from_this<ServerConn>
{
public:
    std::shared_ptr<BaseConn> get_shared_ptr()
    {
        return std::static_pointer_cast<BaseConn>(shared_from_this());
    }
}

class ConnMgr
{
private:
    //there can be more than one connections. Hence using map.
    typedef std:map<socket_addr, std::shared_ptr<BaseConn>> tcp_conn_t;
    tcp_conn_t tcp_conn_;

public:
    void start_connection()
    {
        tcp_conn_[0] = std::make_shared<ClientConn>();
    }

    void handle_new_connection()
    {
        tcp_conn_[0] = std::make_shared<ServerConn>();
    }        
}

0 个答案:

没有答案