user12241860
user12241860

Reputation:

Need help converting structs to class

Note: Code base I am working on is C++98 standard.

I have been trying to convert this code which has been configured as structs, to a class format to be better used with the program I am working on.

In the original code, I can understand how to convert the struct interval_timer to a class (based off my research from here), however I seem to get problems when attempting to convert sections like struct abc_timer : interval_timer. I think understand that this is essenially saying "create struct abc_timer within class interval_timer, but on compile of my code I get several errors.

Original Code

#include <boost/asio.hpp>
#include <iostream>
#include <boost/bind.hpp>
using boost::posix_time::millisec;
using boost::posix_time::seconds;
typedef boost::posix_time::microsec_clock Clock;
using boost::system::error_code;

struct interval_timer
{
  interval_timer(boost::asio::io_context &io, millisec i)
      : interval(i), timer(io)
  {
    run();
  }

  virtual bool callback() = 0;

  void run()
  {
    timer.expires_from_now(interval);
    timer.async_wait(boost::bind(&interval_timer::on_timer, this, boost::asio::placeholders::error()));
  }

  void stop()
  {
    timer.cancel();
  }

private:
  void on_timer(error_code ec)
  {
    if (!ec && callback())
      run();
  }
  millisec const interval;
  boost::asio::deadline_timer timer;
};

int main()
{
  boost::asio::io_context io;

  struct abc_timer : interval_timer
  {
    abc_timer(boost::asio::io_context &io, millisec i) : interval_timer(io, i) {}
    virtual bool callback()
    {
      std::cout << "TEST_ABC" << std::endl;
      return true;
    }
  } abc(io, millisec(200));

  struct counter_timer : interval_timer
  {
    counter_timer(boost::asio::io_context &io, millisec i, interval_timer &abc)
        : interval_timer(io, i), abc(abc), current(0) {}

    virtual bool callback()
    {
      std::cout << "COUNTER AT " << ++current << std::endl;

      if (current < 5)
        return true;

      abc.stop();
      return false;
    }

  private:
    interval_timer &abc;
    int current;
  } counter(io, millisec(1000), abc);

  io.run();
}

My conversion attempt

#include <boost/asio.hpp>
#include <iostream>
#include <boost/bind.hpp>
using boost::posix_time::millisec;
using boost::posix_time::seconds;
typedef boost::posix_time::microsec_clock Clock;
using boost::system::error_code;

boost::asio::io_service io;

class Interval_Timer
{
public:
  Interval_Timer(boost::asio::io_service &io, millisec i);

  virtual bool callback() = 0;
  // boost::asio::io_service io;

public:
  void run();
  void stop();
  void on_timer(error_code ec);

  millisec const interval;
  boost::asio::deadline_timer timer;


public: 
  struct abc_timer
  {
    abc_timer(boost::asio::io_service &io, millisec i) : Interval_Timer(io, i) {}
    virtual bool callback()
    {
      std::cout << "TEST_ABC" << std::endl;
      return true;
    }
  } abc(io, millisec(200));

  struct counter_timer
  {
    counter_timer(boost::asio::io_service &io, millisec i, Interval_Timer &abc)
        : Interval_Timer(io, i), abc(abc), current(0) {}

    virtual bool callback()
    {
      std::cout << "COUNTER AT " << ++current << std::endl;

      if (current < 5)
        return true;

      abc.stop();
      return false;
    }

  private:
    Interval_Timer &abc;
    int current;
  }counter(io, millisec(1000), abc);
};

Interval_Timer::Interval_Timer()
{
}

Interval_Timer::Interval_Timer(boost::asio::io_service &io, millisec i)
    : interval(i), timer(io)
{
  run();
}

Interval_Timer::~Interval_Timer()
{
  std::cout << " DECONSTRUCTED " << std::endl;
}

void Interval_Timer::run()
{
  timer.expires_from_now(interval);
  timer.async_wait(boost::bind(&Interval_Timer::on_timer, this, boost::asio::placeholders::error()));
}

bool Interval_Timer::callback()
{
  std::cout << "TEST_ABC" << std::endl;
  return true;
}

void Interval_Timer::on_timer(error_code ec)
{
  if (!ec && callback())
    run();
}

For lines such as }counter(io, millisec(1000), abc); I get the following error:

error: ‘io’ is not a type

and

error: expected ‘)’ before numeric constant

And for initialisers:

/src/timerTest/execTimer.cpp: In constructor ‘Interval_Timer::counter_timer::counter_timer(boost::asio::io_service&, boost::posix_time::millisec, Interval_Timer&)’:
/src/timerTest/execTimer.cpp:181:11: error: type ‘Interval_Timer’ is not a direct base of ‘Interval_Timer::counter_timer’
         : Interval_Timer(io, i), abc(abc), current(0) {}
           ^

Upvotes: 0

Views: 75

Answers (2)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

Because io is a value that is passed to the Interval_Timer constructor, you can't use it as part of a default value for abc or counter. You'll need to use the member initializer list for the Interval_Timer coustructor.

Interval_Timer::Interval_Timer(boost::asio::io_service &io, millisec i)
    : interval(i), timer(io), abc(io, millisec(100)), counter(io, millisec(1000), abc)
{
    // ...
}

You definitions for abc and counter should be changed to just the variable name, and lose the parameters.

    // ...
    } abc;
    // ...
    } counter;

The default constructor for Interval_Timer should be removed, as the constructors for abc and counter needs to provide a value for io. Or you need to provide new constructors for those two classes so that they can be used in the default constructor without having to specify an io_service.

Upvotes: 0

Isaac Clancy
Isaac Clancy

Reputation: 418

struct abc_timer : interval_timer means that abc_timer inherits from interval_timer e.g. it gains all its members and methods. Converting this to classes would be class abc_timer : public interval_timer

Upvotes: 1

Related Questions