[ASIO] destructor called multiple times in test code

I was messing around with the ASIO timer examples, the examples that test out the asynch-timers. I was trying to remove the Bind calls from those examples.
I stumbled on the following behavior. I created a class function object and overloaded the () operator and would call
t->async_wait(*this);
in the constructor. And
t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
t->async_wait(*this);
in the operator() overload function.
Anyways to make a long story short the destructor that should have only been called once, gets called multiple times, but the constructor gets called once. To make things even funnier, the destructor has no affect when changing the value on member objects.
==================================
Here is the code:
class print{
int count;
boost::asio::deadline_timer* t;
int d_count;
public:
print (boost::asio::io_service& io, boost::asio::deadline_timer* timer)
:count(0), t(timer), d_count(0){
std::cout<<"I'm in constructor: "<

Jose Martinez wrote:
Anyways to make a long story short the destructor that should have only been called once, gets called multiple times, but the constructor gets called once. To make things even funnier, the destructor has no affect when changing the value on member objects.
================================== Here is the code: class print{ int count; boost::asio::deadline_timer* t; int d_count; public: print (boost::asio::io_service& io, boost::asio::deadline_timer* timer) :count(0), t(timer), d_count(0){ std::cout<<"I'm in constructor: "<
async_wait(*this); }//end print ~print(){ std::cout << "Count=" << count << ","; std::cout << " D_count=" << ++d_count << "\n"; }//end ~print
void operator ()(const boost::system::error_code& /*e*/){ if (count < 2){ std::cout << count << "\n"; ++(count); t->expires_at(t->expires_at() + boost::posix_time::seconds(1)); t->async_wait(*this); } }//end void operator() };//end class print
int main(){ boost::asio::io_service io; boost::asio::deadline_timer t(io, boost::posix_time::seconds(1)); print p(io, &t); io.run(); return 0; }
Hi Jose,
If you add a copy constructor and operator= (although operator= doesn't
seem to be used), it will make clear what is happening: p is being
copied repeatedly.
print(const print &p) : count(p.count), t(p.t), d_count(p.d_count){
std::cout<<"I'm in copy constructor: "<

I've been confused by this too -- it comes up frequently. The trick is to instrument every constructor in your class -- even the copy constructor.

Hi! Jose Martinez schrieb:
I stumbled on the following behavior. I created a class function object and overloaded the () operator and would call
t->async_wait(*this);
Function objects are passed by value. This call will copy your object. The other posts already pointed that out. My recommendation is to follow common practise: make the operator() "const": void operator () (/*...*/) const {...} That way you cannot modify members. The "state" of the functor must be stored outside of the functor object. This way the state doesn't get copied. struct FunctorFoo { FunctorFoo(int& counter) : counter(&counter) {} int* const counter; void operator() () const { ++*counter; } }; (you could also use a "int& counter" member) Frank
participants (4)
-
David Walthall
-
Frank Birbacher
-
Jose Martinez
-
Nat Goodspeed