Jake B.
Jake B.

Reputation: 465

Using a "superclass" object to handle inherited classes

I am making a program that solves a number of similar problems.

I am starting with a class that looks like (for example):

class problem {
  void init();
  void solve();
  int print_result();
}

but then I would like to extend this class to different problems:

class problem_A : problem {
  void init();
  void solve();
  void print_result();
}

class problem_B : problem {
  void init();
  void solve();
  void print_result();
}

...

But in the main interface I would like to have a single object for either of the problems (A, B, ...) and handle them like:

obj.init();
obj.solve();
obj.print_result();

How do I achieve this? What type should obj be?

Upvotes: 1

Views: 73

Answers (2)

Barry
Barry

Reputation: 302827

If you always want to call init() then solve() then print_result(), it's best to wrap this up in the (for C++) awkwardly named Template Method Pattern:

class problem {
public:
    virtual ~problem() = default;

    void run() {
        init();
        solve();
        print_result();
    }

protected:
    virtual void init() = 0;
    virtual void solve() = 0;
    virtual void print_result() = 0;
};

And then each of your explicit problems just have to provide implementations for those functions:

class problem_A : public problem {
protected:
    void init() override { .. }
    void solve() override { .. }
    void print_result() override { .. }
};

problem* p = new problem_A(..);
p->run(); // inits, solves, and prints the results for problem A

Upvotes: 2

Cory Kramer
Cory Kramer

Reputation: 117856

You stick with your original class, but make the methods pure virtual

class problem {
  virtual void init() = 0;
  virtual void solve() = 0;
  virtual int print_result() = 0;
}

Then you can override these functions in the derived classes

class problem_A : problem {
  virtual void init() override;
  virtual void solve() override;
  virtual void print_result() override;
}

Then you can make your object as follows:

problem* obj = new problem_A;
obj->init();
obj->solve();
obj->print_result();

This will invoke problem_A's methods, but you can use a pointer to the base class problem. Obviously make sure you clean up the memory

delete obj;

Or use smart pointers

std::unique_ptr<problem> = std::unique_ptr<problem>(new problem_A);

Upvotes: 1

Related Questions