Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enforce order of function calls?

Say I have a abstract base class and I want to have a pure virtual method which must be implemented by the derived class but I want to make sure that the derived method calls functions in a particular order what could I do to enforce it ?

I.E

base class
virtual void doABC()=0;
virtual void A()=0;
virtual void B()=0;
virtual void C()=0;


// must call ABC in the correct order 
derived class public base
void doABC();

This is just so I have a better understanding on how to design my classes to enforce someone to use my class correctly.

like image 502
gda2004 Avatar asked May 15 '12 13:05

gda2004


3 Answers

You're looking for the template method pattern:

http://en.wikipedia.org/wiki/Template_method_pattern

Something along these lines:

class BaseAlgorithm
{
protected:
    virtual void firstStep() = 0;
    virtual void secondStep() = 0;
    virtual void finalStep() = 0;
public:
    void runAlgorithm()
    {
        firstStep();
        secondStep();
        finalStep();
    }
};

class ConcreteAlgorithm : BaseAlgorithm
{
    virtual void firstStep() {};
    virtual void secondStep() {};
    virtual void finalStep() {};
};

You basically force extending classes to implement all intermediate steps, but you keep them protected or private - document this - and only call runAlgorithm(), which ties the smaller pieces together.

like image 193
Luchian Grigore Avatar answered Sep 28 '22 01:09

Luchian Grigore


There are actually two particular ways, depending on whether you go with inheritance or parameterization.

If you with inheritance, it is the Template Method pattern:

class Base {
public:
    void doit() {
        this->do1();
        this->do2();
    }
private:
    virtual void do1() = 0;
    virtual void do2() = 0;
};

And if you go with parameterization, it is the Strategy pattern:

class Strategy {
public:
    virtual void do1() = 0;
    virtual void do2() = 0;
};

void doit(Strategy& s) {
    s.do1();
    s.do2();
}

From the website:

Strategy is like Template Method except in its granularity. [Coplien, C++ Report, Mar 96, p88]

Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm. [GoF, p330]

Strategy modifies the logic of individual objects. Template Method modifies the logic of an entire class. [Grand, p383]

I recommend you familiarize yourself with them.

like image 35
Matthieu M. Avatar answered Sep 28 '22 00:09

Matthieu M.


The simplest answer could be if You remove virtual from doABC(), so that it can not be derived by child class. Call the virtual methods inside doABC() in correct order.

like image 35
Anand Avatar answered Sep 28 '22 01:09

Anand