3

I have an generic math-method, that operates under a set of functions (with a lot of variables and states, so it can't be static). I've implemented method in parent class and I want to declare a different set of functions in every child-class.
I've try to do something like this:

class A {
public:
    typedef int (A::*func)();
    func * fs;
    void f() { /*call functions from this->fs*/ }
};

class B : public A {
public:
    int smth;

    B(int smth) {
         this->smth = smth; //user-provided variables

        //there may be a lot of functions with same interface
        this->fs = new func[1];
        fs[0] = &B::f;
    }

    int f() {
        return smth + 1;
    }
};

It fails with this error: error C2440: '=' : cannot convert from 'int (__thiscall B::* )(void)' to 'A::func'

Or "IntelliSense: a pointer to a bound function may only be used to call the function" if I try to use &this->f;

5
  • I don't understand what you're trying to do. Please expand further. Commented Jun 16, 2010 at 20:57
  • What's your bigger picture here? Also, use std::vector instead of manual allocation. Commented Jun 16, 2010 at 20:57
  • 1
    Is there a reason you can't refactor your application to use virtual functions? It seems like you're trying to reimplement a language feature. Commented Jun 16, 2010 at 20:58
  • This sounds like you want polymorphic behaviour as provided by virtual functions but the question is really unclear – what exactly are you trying to accomplish? Commented Jun 16, 2010 at 20:59
  • I have an generic math-method, that operates under a set of functions (with a lot of variables and states). I've implemented method in parent class and I want to declare a different set of functions in every child-class. Commented Jun 16, 2010 at 21:05

2 Answers 2

2

Curiously recurring template pattern would help.

template<typename Derived>
class A {
public:
    typedef int (Derived::*func)();
    func * fs;
    void f()
    {
        Derived* const This = static_cast<Derived*>(this);
        /* call functions like (This->*(fs[0]))() */
    }
};

class B : public A<B> {
public:
    int smth;

    B(int smth) {
         this->smth = smth; //user-provided variables

        //there may be a lot of functions with same interface
        this->fs = new func[1];
        fs[0] = &B::f;
    }

    int f() {
        return smth + 1;
    }
};
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, that work exactly how I want and can be implemented with minor changes in code :)
How is this different than not just using B and putting it's functions in an array? (i.e., what purpose does A serve?)
I can have a lot of math-models (B's) and only one method to solve them (A).
@pingvinus: But there is no single A.
@GMan: presumably what is missing is the count of fs. It would probably be better to use a std::vector<func> instead. Consider for example, that A might implement performance comparison between a number of different algorithms defined in B. A needs to be able to access and time each algorithm independently, but it also needs to have access to the whole set so it can compare the results and make sure they agree within acceptable precision. Also the inputs are stored in member variables of B so that all the algorithms have access to them. Just one example of a good use for this.
1

Maybe an array of boost::function would work:

#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <vector>

struct A
{
    virtual ~A(void) {}; // base classes should always have virtual destructors

    typedef std::vector<boost::function<int(void)> > function_array;
    function_array mFunctions;
};

struct B : A
{
    B(int pX) : mX(pX) // use initializer lists
    {
        mFunctions.push_back(boost::lambda::bind(&B::foo, this));
    }

    int foo(void)
    {
        return mX + 1;
    }

    int mX;
};

int main(void)
{
    B b(5);
    A& a(b);

    int x = a.mFunctions[0]();
    // x is 6
}

Your goals are still unclear. (In the above, it doesn't really make sense for A to be a base class. Why not have a function like get_functions that just returns an array of functions all setup and ready to use, for example?)


What's your bigger picture here? Sounds like you're looking for virtual functions:

struct A
{
    virtual ~A(void) {} // base classes should always have virtual destructors

    virtual int foo(void) const = 0;
};

struct B : A
{
    B(int pX) : mX(pX) {}

    int foo(void) const
    {
        return mX + 1;
    }

    int mX;
};

int main(void)
{
    B b(5);
    A* a = &b;

    int x = a->f(); // calls B::foo(), polymorphic behavior thanks to virtual
    // x is 6
}

2 Comments

I can't use virtual functions, because number of them may vary in every child-class.
@pingvinus: Then you'll have to enlighten us on what the bigger picture is. Show us your goals, not the method you think you need to get there. (That's what we're for.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.