I want to create some Timer
class, which prints "text" every N seconds, where N will be initialized in constructor.
#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;
}
But I have bad_weak_ptr
error.
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
What am I doing wrong and how can I fix it?
Defined in header <memory> class bad_weak_ptr; (since C++11) std::bad_weak_ptr is the type of the object thrown as exceptions by the constructors of std::shared_ptr that take std::weak_ptr as the argument, when the std::weak_ptr refers to an already deleted object.
Second, notice that the weak pointer is set only when the object is placed inside a shared_ptr , which happens after the shared object has been constructed. This means that you cannot use shared_from_this() in your constructor.
Before calling shared_from_this()
your class needs to be stored in a shared_ptr
. This means that you cannot call shared_from_this()
inside the constructor, because the line the object won't be placed into the shared_ptr until after the constructor is finished.
This is the reason that classes which use enable_shared_from_this
typically have a start
function which does the final steps of initialization that require the use of shared_from_this()
. That start function needs to be called after the object is completely constructed, and so cannot be called from inside the constructor as you are doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With