c ++ bad_weak_ptr错误

ДМИ*_*КОВ 13 c++ boost

我想创建一个Timer类,每隔N秒打印一次"文本",其中N将在构造函数中初始化.

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

#include <iostream>

class Timer : public boost::enable_shared_from_this<Timer>
{
public:
    Timer ( const double interval ) : interval_sec( interval )
    {
        io_service_ = new boost::asio::io_service;
        timer_      = new boost::asio::deadline_timer ( * io_service_ );
        start( );
        io_service_ -> run( );
    }

    void start ( )
    {
        timer_ -> expires_from_now( boost::posix_time::seconds( 0 ) );
        timer_ -> async_wait(boost::bind( &Timer::handler
                                        , shared_from_this( )
                                        , boost::asio::placeholders::error
                                        )
                            );
    }

private:
    void handler( const boost::system::error_code& error )
    {
        if ( error )
        {
            std::cerr << error.message( ) << std::endl;
            return;
        }

        printf( "text\n" );
        timer_ -> expires_from_now( boost::posix_time::seconds( interval_sec ) );
        timer_ -> async_wait( boost::bind( &Timer::handler
                                         , shared_from_this( )
                                         , boost::asio::placeholders::error
                                         )
                            );
    }

private:
    boost::asio::io_service * io_service_;
    boost::asio::deadline_timer * timer_;
    double interval_sec;
};

int main()
{
    boost::shared_ptr<Timer> timer( new Timer ( 10 ) );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但我有bad_weak_ptr错误.

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
  what():  tr1::bad_weak_ptr
Aborted
Run Code Online (Sandbox Code Playgroud)

我做错了什么,我该如何解决?

Dav*_*eas 27

问题很可能是shared_from_this在对象实际由共享指针管理之前无法使用.一般来说它不是启动一个线程或异步服务在构造函数中,你可能是不幸的,并在构造函数完成之前,新线程可能会启动,从而执行一个不完全构造的对象上一个好主意.

在您的特定情况下,甚至更糟,因为你进入你的构造函数中的事件循环Timer类,这意味着控制从未返回main,对象是永远不会被管理的shared_ptr主...

你应该将调用start和调用移动run()到另一个函数,然后main 实际管理对象之后调用它shared_ptr.


Soa*_*Box 11

在调用shared_from_this()你的课之前需要存储一个shared_ptr.这意味着您无法shared_from_this()在构造函数内部调用,因为直到构造函数完成之后,对象才会被放入shared_ptr中.

这就是因为使用的类enable_shared_from_this通常具有start执行需要使用的初始化的最后步骤的函数的原因shared_from_this().在完全构造对象之后需要调用该start函数,因此无法像在执行时那样从构造函数内部调用.