I have this classes:
class Foo
{
...
};
class Foo1 : public Foo
{
...
};
...
class FooN : public Foo
{
...
};
Is it possible to have an array of functions with these kind of signatures:
void f1(Foo1*){}
...
void fN(FooN*){}
Is there any change if these functions are non static member functions instead of regular functions? I don't think this will change something.
Thanks!
EDIT alternative non-virtual-function-based solution here.
The type void(*)(Foo*)
is not convertible to the type void(*)(Bar*)
and for good reason.
You should make all your functions take an Interface*
argument and all the FooN
should derive from Interface
struct Interface {
virtual ~ Interface () {}
// ...
};
struct Foo1 : public Interface {
// ...
};
struct Foo2 : public Interface {
// ...
};
void f1 (Interface *);
void f2 (Interface *);
void (*functions)(Interface*) [] = {f1, f2};
functions[0] (new Foo1 ());
functions[0] (new Foo2 ());
functions[1] (new Foo1 ());
functions[1] (new Foo2 ());
The implementations of f1
, f2
can check at runtime if their argument is a particular implementation by using dynamic_cast
and checking for nullptr
. The only way to check at compile time is to make f1
and f2
take specific types and not put them in an anonymous array, but invoke them explicitly.
To answer the second part of your question -- yes it DOES matter if they're non-static member functions because the size of the pointer is not constant
You could use function objects. See the example below on how to do it yourselve. If you like the idea you should have a look at boost.signal/boost.bind and the c++ 0x counterparts.
class Foo1 {};
class Foo2 {};
class Foo3 {};
void func1(Foo1*) {}
void func2(Foo2*) {}
void func3(Foo3*) {}
class FuncObjBase {
public:
virtual void operator()() = 0;
};
template <class T>
class FuncObj : public FuncObjBase {
public:
typedef void (*Funcptr)(T*);
FuncObj(T* instance, Funcptr funcptr) : m_Instance(instance), m_Func(funcptr) {}
virtual void operator()() { m_Func(m_Instance); }
private:
T* m_Instance;
Funcptr m_Func;
};
int main(int argc, char *argv[])
{
Foo1 foo1;
Foo2 foo2;
Foo3 foo3;
FuncObjBase* functions[3];
functions[0] = new FuncObj<Foo1>(&foo1, func1);
functions[1] = new FuncObj<Foo2>(&foo2, func2);
functions[2] = new FuncObj<Foo3>(&foo3, func3);
for(unsigned int i = 0; i < 3; i++) {
(*functions[i])();
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With