How can I choose the algorithm of a code only once at the beginning in C++?

Viewed 110

There are two different algorithms being used throughout the code. Which one is chosen is determined at runtime by a parameter (e.g. true or false). I do not want to use if-statements each time the algorithm comes up.

So instead of writing the following every time

if (parameter==true)
    algorithmOne();
else
    algorithmTwo();

I want to set the algorithm at the beginning, like

if (parameter==true)
    algorithm()=algorithmOne();
else
    algorithm()=algorithmTwo();

and only use 'algorithm()' from this point forward.

How can I choose the algorithm at the beginning depending on a parameter after the code is already compiled?

Edit: How do you do that within the constructor of a class (since a pointer-to-member function is no regular pointer)? As both algorithms rely on member variables and functions of this class, it is inconvenient to derive a new class.

Solution: This could be solved with a virtual function and derived classes.

class Base
{
public:
    Base();
    virtual void algorithm() = 0;
    ~Base();
protected:
    double d;
    int i;
    ...
}

class DerivedOne : public Base
{
public:
    DerivedOne() : Noise() {};
    void algorithm() override;
    ~DerivedOne();
};

Base *b;

if (parameter==true)
    {
        b = new DerivedOne();
    }
    else
    {
        b = new DerivedTwo();
    }

Then the function can be called with:

b->algorithm();

And deleted with:

delete b;

This may not be the best way but it seems to work for me. See answers and comments.

3 Answers

You're almost there:

auto algorithm = parameter ? algorithmOne : algorithmTwo.

No (), you're not trying to call any function here.

The answer you are looking for is likely a function/method pointer.

The syntax for a function pointer is as follows:

typedef void (*MyFunctionPointer)();
MyFunctionPointer *algorithm;

void function(bool parameter)
{
    if (parameter)
        algorithm = &myFirstAlgo;
    else
        algorithm = &mySecondAlgo;
}

void anotherFunction()
{
    algorithm();
}

Please note that this approach works for C, C++03 and C++11. If you want to use auto on the global scope, you need to give it a default value.

The object-oriented way of doing this would be to define a base class with the algorithm interface:

class AlgorithmBase
{
public:
    virtual void algorithm() = 0;
    virtual ~AlgorithmBase() {}  // virtual destructor may be needed
};

Then implement classes for the different algorithm implementations:

class AlgorithmOne: public AlgorithmBase
{
public:
    virtual void algorithm();
};

void AlgorithmOne::algorithm()
{
   ...
}

and similarly for AlgorithmTwo and other implementations.

Now, you can define a pointer to an algorithm object containing the selected implementation and use that whenever the algorithm shall be executed:

   AlgorithmBase *algorithm = 0;
   if(parameter)
   {
      algorithm = new AlgorithmOne();
   }
   else
   {
      algorithm = new AlgorithmTwo();
   }

   ...
   algorithm->algorithm();  // Call the selected algorithm

   ...
   delete algorithm;  // Destroy algorithm instance before exiting
Related