How to switch between 2 sets of functions in C ++?

Is there any way I can effectively switch between 2 similar sets of functions (C / C ++)? To better explain what I mean, let's say I have two sets of global functions, such as:

void a_someCoolFunction();
void a_anotherCoolFunction(int withParameters);

void b_someCoolFunction();
void b_anotherCoolFunction(int withParameters);

And I want to "switch" in my program at run time, which is used. BUT: I do not want to have one if condition with each function, for example:

void inline someCoolFunction(){
    if(someState = A_STATE){
        a_someCoolFunction();
    }else{
        b_someCoolFunction();
    }
}

Because I expect each function to be called a lot in my mainloop - so it would be preferable if I could do something like this (when starting my mainloop or when someState changes):

if(someState = A_STATE){
    useFunctionsOfType = a;
}else{
    useFunctionsOfType = b;
}

and then just call

useFunctionsOfType _someCoolFunction();

, , ... : , OpenGL ES 1.1 OpenGL ES 2.0, 2 (: renderOpenGL1() renderOpenGL2() render()). : glLoadIdentity(); myLoadIdentity();... - . ?

+5
7

C (, , C, ++), .

// Globals. Default to the a_ functions
void(*theCoolFunction)()           = a_someCoolFunction;
void(*theOtherCoolFunction)(int)   = a_anotherCoolFunction;

// In the code ...
{
  ...
  // use the other functions 
  theCoolFunction = b_someCoolFunction;
  theOtherCoolFunction = b_anotherCoolFunction;
  ...
}

, , . , , , :

   void (*functions_a[2])();
   void (*functions_b[2])();

   void (**functions)() = functions_a;

   ....
   #define theCoolFunction()       functions[0]()
   #define theOtherCoolFunction(x) functions[1](x) 
   ....

    // switch grooup:
   functions = functions_b;

( , ).

, ++ ( ++!)

+2

, ( ):

  • .
  • .
  • .

, , , , - .

+8

, , ++, ( ?), .

API, :

class OpenGLAbstract
{
   public:
       virtual ~OpenGLAbstract() {}
       virtual void loadIdentity() = 0;
       virtual void someFunction() = 0;
};

class OpenGLEs11 : public OpenGLAbstract
{
   public:
       virtual void loadIdentity()  
       {
           // Call 1.1 API

       }
       virtual void someFunction() 
       {
           // Call 1.1 API
       }
};


class OpenGLEs20 : public OpenGLAbstract
{
   public:
       virtual void loadIdentity()  
       {
           // Call 2.0 API
       }
       virtual void someFunction() 
       {
           // Call 2.0 API
       }
};

int main()
{
    // Select the API to use:
    bool want11 = true;
    OpenGLAbstract* gl = 0;
    if (want11)
        gl = new OpenGLEs11;
    else
        gl = new OpenGLEs20;

    // In the main loop.
    gl->loadIdentity();

    delete gl;
}

, , ++, , ++ , .

, , , 2.0 , 2.0. API- ( ). OpenGL factory :

OpenGlAbstract* create();

create() API.

+4

. , , .

, , , "" . :

typedef int (*func_t)(int);


int divide(int x) {
    return x / 2;
}

int multiply(int x) {
    return x * 2;
}

int main() {
    func_t f = ÷
    f(2); //returns 1
    f = &multiply;
    f(2); //returns 4
}
+2

- boost:: function (std:: function) . :

#include <iostream>
#include <boost/function.hpp> //requires boost installation
#include <functional> //c++0x header


void a_coolFunction() {

    std::cout << "Calling a_coolFunction()" << std::endl;
}

void a_coolFunction(int param) {

     std::cout << "Calling a_coolFunction(" << param << ")" << std::endl;
}

void b_coolFunction() {

    std::cout << "Calling b_coolFunction()" << std::endl;
}

void b_coolFunction(int param) {

    std::cout << "Calling b_coolFunction(" << param << ")" << std::endl;
}
float mul_ints(int x, int y) {return ((float)x)*y;}


int main() {

    std::function<void()> f1;  //included in c++0x 
    boost::function<void(int)> f2; //boost, works with current c++
    boost::function<float(int,int)> f3;

    //casts are necessary to resolve overloaded functions
    //otherwise you don't need them
   f1 = static_cast<void(*)()>(a_coolFunction);
   f2 = static_cast<void(*)(int)>(a_coolFunction);

   f1();
   f2(5);

   //switching
   f1 = static_cast<void(*)()>(b_coolFunction);
   f2 = static_cast<void(*)(int)>(b_coolFunction);

   f1();
   f2(7);

   //example from boost::function documentation.  No cast required.
   f3 = mul_ints;
   std::cout << f3(5,3) << std::endl;

}

g++ - 4.4.4, :

Calling a_coolFunction()
Calling a_coolFunction(5)
Calling b_coolFunction()
Calling b_coolFunction(7)
15

, f1, f2 .. , , , (.. void (int) f2).

+2

.

But the best way is to use something similar to an abstract factory design template. A good general implementation can be found in the Loki library .

+1
source

In C, you usually do this with pointers to struct:

struct functiontable {
    void (*someCoolFunction)(void);
    void (*anotherCoolFunction)(int);
};

const struct functiontable table_a = { &a_someCoolFunction, &a_anotherCoolFunction };
const struct functiontable table_b = { &b_someCoolFunction, &b_anotherCoolFunction };

const struct functiontable *ftable = NULL;

To switch the active function table, you should use:

ftable = &table_a;

To call functions, you should use:

ftable->someCoolFunction();
+1
source

All Articles