簡體   English   中英

來自 shared_from_this() 的 std::bad_weak_ptr

[英]std::bad_weak_ptr from shared_from_this()

我正在構建一個異步程序,其中boost::asio::io_context有一個指向我的 object 的共享指針。當我的 object 停止發布帶有回調的異步工作時,我的 object 應該死掉。

我正在使用std::enable_shared_from_this<T>::shared_from_this()將我自己的引用提供給上下文。 但是,當我調用 shared_from_this shared_from_this()時,會拋出一個std::bad_weak_ptr

cppreference說:

允許在先前共享的 object 上調用 shared_from_this,即在由std::shared_ptr管理的 object 上調用(特別是,在*this的構造期間不能調用shared_from_this )。 std::bad_weak_ptr被拋出(由來自默認構造的 weak_this 的shared_ptr構造函數)(C++17 起)。

我正在使用std::make_shared<...>()創建 object ,所以我認為“先前共享的對象”已得到滿足。 我怎樣才能避免這個例外?

MCVE:

// :! g++ % -std=c++17 && ./a.out
#include <memory>

class Object : std::enable_shared_from_this<Object> {
public:
    std::shared_ptr<Object> get() { return shared_from_this(); }
};

int main()
{
    std::make_shared<Object>()->get();
}

我能夠編譯/運行來自 Boost.Beast 的示例代碼,它可以毫無問題地執行完全相同的操作。 我不確定我的代碼和鏈接示例之間有什么區別。 該示例如下所示:

// Accepts incoming connections and launches the sessions
class listener : public std::enable_shared_from_this<listener>
{
    net::io_context& ioc_;
    ...

    void run()
    {
        // The new connection gets its own strand
        acceptor_.async_accept(
            net::make_strand(ioc_),
            beast::bind_front_handler(
                &listener::on_accept,
                shared_from_this()));
    }
    ...
};

int main(int argc, char* argv[])
{
    ...
    // The io_context is required for all I/O
    net::io_context ioc{threads};

    // Create and launch a listening port
    std::make_shared<listener>(ioc, ...)->run();
    ...
    ioc.run();
    ...
}

為了完成,有時您只需要第二雙眼睛。

當 inheritance 為私有時,此行為發生在gcc (在其他實現中未確認)。

更正后的 MCVE:

// :! g++ % -std=c++17 && ./a.out
#include <memory>

class Object : public std::enable_shared_from_this<Object> {
public:
    std::shared_ptr<Object> get() { return shared_from_this(); }
};

int main()
{
    std::make_shared<Object>()->get();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM