Hi all,

I've found a few references that address this issue, however I haven't figured out what the solution is in the specific case that I'm dealing with. Hopefully someone can help me out. The following code prototypes the general idea that I'm working with:

class FooClass
{
public:
    typedef void ( *pointerToDoubleTakingFunction ) ( double& );

    FooClass(){};

    ~FooClass(){};

    void setDoubleTakingFunction( pointerToDoubleTakingFunction
                                                  pDoubleTakingFunction )
    {
        pointerToDoubleTakingFunction_ = pDoubleTakingFunction;
    };

protected:
    pointerToDoubleTakingFunction pointerToDoubleTakingFunction_;
};

class BaseClass
{
public:
    BaseClass(){};
    
    virtual ~BaseClass(){};

    virtual void computeFoo( double& fooValue ) =0;
}

class DerivedClass : public BaseClass
{
public:
   DerivedClass(){};
    
    ~DerivedClass(){};

    void setFooClassObject( FooClass* pointerToFooClassObject )
    {
        fooClassObject_ = fooClassObject;
    };

    void run()
    {
        fooClassObject_->setDoubleTakingFunction( &computeFoo );
    };

    void computeFoo( double& fooValue )
    {
        fooValue = fooValue * 2.0;        
    };

private:
    FooClass fooClassObject_;
    
};

int main()
{

FooClass* pointerToFooClass = new instanceOfFooClass;

DerivedClass instanceOfDerivedClass;

instanceOfDerivedClass.setFooClassObject( pointerToFooClass );

instanceOfDerivedClass.run();

return 0;
};

I think this summarizes the gist of what I am attempting. Basically, I need to pass the non-static member function computeFoo() in DerivedClass to FooClass automatically, via the run() function in DerivedClass. Passing the address of computeFoo() doesn't work and I've tried following a few references on passing non-static member functions but nothing really works.

If anyone can help me sort this out, I would greatly appreciate it.

Thanks in advance!

Cheers,

Kartik

Recommended Answers

All 14 Replies

AFAIK, passing pointer to class member function need you specify class Name also, i.e

typedef void ( FooClass::*pointerToDoubleTakingFunction ) ( double& );

See this link for more info

This is an issue that comes up once in a while on this forum and others.

The first option that you can consider is the one that you are already trying to implement and with the link in evstevemd's post, it shouldn't be a problem to fix the syntax.

However, I personally rarely see the use of pointers to member functions because it can more easily be implemented with an interface class and multiple inheritance, without any more restriction than those already imposed by the pointer-to-method solution. Here is an example of that that I had previously posted sometime ago (for a "button release" callback function):

#include <iostream>
//define an interface class for all the responder classes 
class ReleaseResponder {
  public:
    virtual void OnRelease() = 0; //with a pure virtual response function (callback).
};

//hold a pointer to that interface class in the Button class:
class Button {
  private:
    ReleaseResponder* responder;
  public:
    Button() : responder(NULL) { };
    void setActionOnReleased(ReleaseResponder* aResponder ) { 
      responder = aResponder;
    };
    void mouseReleased() {
      std::cout << "mouse released" << std::endl;
      if(responder)
        responder->OnRelease();
    };
};

//Make whatever class you want to use as responder implement the responder interface:
class AClass : public ReleaseResponder {
  public:
    //....
    void OnRelease() {
      std::cout << "responding..." << std::endl;
    };
};

//then you set it up as:
int main() {
  AClass* myResponder = new AClass();
  Button* myButton = new Button();
  myButton->setActionOnReleased(myResponder);
  //test it:
  myButton->mouseRelease();
  return 0;
};

The third option that is good if you really don't want any restrictions as to what you can use as the function pointer (static method, non-static method, global function, function-object, whatever). This uses generic programming concepts, so it is a bit more advanced, but far more flexible. Here was my reiteration of the above example:

#include <iostream>

//define a default policy class for all the responder policies 
struct NoRespondPolicy {
  void operator()() {
    std::cout << "not responding..." << std::endl;
  };
};

//make the Button class templated with the responding policy:
template<class OnRelease = NoRespondPolicy>
class Button {
  private:
    OnRelease responder;
  public:
    Button() { };
    Button(OnRelease aResponder) : responder(aResponder) { };
    void setActionOnReleased(OnRelease aResponder ) { 
      responder = aResponder;
    };
    void mouseReleased() {
      std::cout << "mouse released" << std::endl;
      responder();
    };
};

//create a special policy for pointer to member functions:
template<class T>
class MemberFuncRespond {
  public:
    typedef void (T::*VoidFuncPtr)();
  private:
    T* Obj;
    VoidFuncPtr Func;
  public:
    MemberFuncRespond(T* aObj, VoidFuncPtr aFunc) : Obj(aObj), Func(aFunc) { };
    void operator() () {
      if(Obj)
        (Obj->*Func)();
    };
};

//Make whatever class you want to use as respond:
class AClass {
  public:
    //....
    void OnRelease() {
      std::cout << "responding with on release function..." << std::endl;
    };
    typedef void (AClass::*VoidFunc)();
    typedef MemberFuncRespond<AClass> Responder;
    Responder getResponder(VoidFunc FPtr) { return Responder(this,FPtr); };

    void operator()() {
      std::cout << "responding with operator ()..." << std::endl;
    };
};

void GlobalOnRelease() {
  std::cout << "responding with global function..." << std::endl;
};

//then you set it up as:
int main() {
  AClass myResponder;

  Button<> myButton1; //no response (default policy)  
  myButton1.mouseReleased();

  Button<AClass&> myButton2(myResponder); //respond with AClass.operator()
  myButton2.mouseReleased();

  Button< AClass::Responder > myButton3(myResponder.getResponder(&AClass::OnRelease)); //respond with AClass.OnRelease()
  myButton3.mouseReleased();

  Button<void (*)()> myButton4(&GlobalOnRelease); //respond with GlobalOnRelease()
  myButton4.mouseReleased();

  return 0;
};

Hope this helps.

Thanks for all the feedback.

I'm not sure my problem is entirely solved by this.

The issue I have is as follows in terms of the code I provided initially:

class FooClass
{
public:
    typedef void ( *pointerToDoubleTakingFunction ) ( double& );

    typedef void ( DerivedClass::*pointerToComputeFoo ) ( double& );

    FooClass(){};

    virtual ~FooClass(){};

    void setDoubleTakingFunction( pointerToDoubleTakingFunction
                                                  pDoubleTakingFunction )
    {
        pointerToDoubleTakingFunction_ = pDoubleTakingFunction;
    };

    void setDoubleTakingFunction( pointerToComputeFoo
                                                  pComputeFoo )
    {
        pointerToComputeFoo_ = pComputeFoo;
    };

    void setDouble( double doubleValue )
    {
        doubleValue_ = doubleValue;
    }

    virtual void run() =0;

protected:
    pointerToDoubleTakingFunction pointerToDoubleTakingFunction_;

    pointerToComputeFoo pointerToComputeFoo_;

    double doubleValue_;
};

class DerivedFooClass: public FooClass
{
public:
    void run()
    {
            // This needs to be a general pointer container since users should only be required
            // to implement the run() function once, and not have to create one for each case of
            // function-pointer.
            // This implementation of run() uses the global function pointer and I need a way of
            // also dealing with the member function pointer automatically.
            pointerToDoubleTakingFunction_( doubleValue_ );
    };
};

class BaseClass
{
public:
    BaseClass(){};
    
    virtual ~BaseClass(){};

    virtual void computeFoo( double& fooValue ) =0;
}

class DerivedClass : public BaseClass
{
public:
   DerivedClass(){};
    
    ~DerivedClass(){};

    void setFooClassObject( FooClass* pointerToFooClassObject )
    {
        fooClassObject_ = fooClassObject;
    };

    void run()
    {
        fooClassObject_->setDoubleTakingFunction( &computeFoo );
        fooClassObject_->run()
    };

    void computeFoo( double& fooValue )
    {
        fooValue = fooValue * 2.0;        
    };

private:
    FooClass fooClassObject_;
    
};

void computeFooGlobalFunction( double& fooValue )
{
    fooValue = fooValue * 4.0;
};

int main()
{

// This is the usage for a member function
// Create pointer to a FooClass object
FooClass* pointerToFooClass = new instanceOfFooClass;
// Create an instance of DerivedClass
DerivedClass instanceOfDerivedClass;
// Set pointer to FooClass in instance of DerivedClass
instanceOfDerivedClass.setFooClassObject( pointerToFooClass );
// Call run function of DerivedClass
instanceOfDerivedClass.run();

// Create FooClass object
FooClass fooClassObject;
// Set global function as double-taking function in FooClass object
fooClassObject.setDoubleTakingFunction( &computeFooGlobalFunction );

return 0;
};

The issue I have is with user-interface. I am working on a C++ library that has to be easy to use for people with "basic" C++ knowledge.

The idea is that users are also developers of the library, and with the necessary architecture, these users have to be able to create new derived classes of FooClass, which only requires them to fill out the details of the run() function once. This run function has to be able to call on a function pointer that can point to both global functions and member functions.

I've created two typedefs in FooClass that illustrate my problem.

The first typedef is of a pointer-to-function type, which allows me to use the interface in the main of setting a global function address in the setDoubleTakingFunction() function.

The second typedef is of a pointer-to-member function type, which allows me to use the run() function in DerivedClass to execute the run() function in FooClass. For this to be possible though, I have to pass the address of the member function computeFoo() to FooClass, and the second typedef and its use allows for this, as I've overloaded the setDoubleTakingFunction().

The problem however is that I need a generic pointer that I can give the users who are developing new derived classes of FooClass, so that they can just concentrate on developing the run() function, without dealing with the rest of the architecture.

I've spent some time reading about this and discovered that there is no void-pointer-type idea for function-pointers like there is for variable-pointers (I've read it's possible sometimes, but really not a good idea to do).

So that's basically where I'm stuck now.

From what I understand, I can't use the multiple-inheritance or functors methods because they cause the user-interface that I need to change. I don't seem to be able to use the functor/functionoid method either because that requires that the functions be placed in objects I believe, and I still need to be able to pass global functions to FooClass.

I hope this has clarified the issue I am facing and I hope someone can help me sort this out.

It's turning my head into goo at the moment :P

Cheers,

Kartik

Ok, so from what I understand, you need basically the freedom of the generic programming option without using anything "too complicated for the users of your library". In other words, you want to avoid templates, policy classes, even multiple inheritance... essentially anything outside the capabilities of a very novice programmer (who probably should not touch your library anyways, or any other libraries for that matter).

To solve the problem, there is little you can do to mimic generic programming at run-time (not at compile time with templates) without adding overhead (time + memory), but I guess that doesn't matter to you. Building on your code, the simplest solution is abstraction, which can be realized in two different ways here:

class BaseClass; //forward-declaration.

class FooClass
{
  public:
    typedef void ( *pointerToDoubleTakingFunction ) ( double& );
    typedef void ( BaseClass::*pointerToComputeFoo ) ( double& ); //note BaseClass here.
  private:
    pointerToDoubleTakingFunction pointerToDoubleTakingFunction_;
    pointerToComputeFoo pointerToComputeFoo_;
    BaseClass* pointerToBase_; //note: you need a pointer to BaseClass in order to call pointerToComputeFoo_
  public:
    FooClass() : pointerToDoubleTakingFunction_(NULL),
                 pointerToComputeFoo_(NULL), pointerToBase_(NULL) {};

    virtual ~FooClass() {};

    void setDoubleTakingFunction( pointerToDoubleTakingFunction
                                                  pDoubleTakingFunction )
    {
        pointerToDoubleTakingFunction_ = pDoubleTakingFunction;
        pointerToComputeFoo_ = NULL;
        pointerToBase_ = NULL; //note the two options are mutually exclusive.
    };

    void setDoubleTakingFunction( pointerToComputeFoo
                                                  pComputeFoo, BaseClass* pBase )
    {
        pointerToComputeFoo_ = pComputeFoo;
        pointerToBase_ = pBase;
        pointerToDoubleTakingFunction_ = NULL; //again, mutual exclusion.
    };

    void setDouble( double doubleValue )
    {
        doubleValue_ = doubleValue;
    }

    //OPTION 1: as before
    virtual void run_OPTION1() = 0;

    //OPTION 2: implement a public run function that calls a protected virtual run function (see below)
    void run_public_OPTION2() {
      run_OPTION2(); //call virtual function (derived class implementation).
      ComputeDoubleTakingFunction(doubleValue_);
    };

protected:
    
    double doubleValue_;

    //OPTION 1: make a protected function for the derived class to call that abstracts the details of whether it is a global function or member function.
    void ComputeDoubleTakingFunction(double aValue) {
      if(pointerToDoubleTakingFunction_)
        pointerToDoubleTakingFunction_(aValue);
      else if((pointerToComputeFoo_) && (pointerToBase_))
        pointerToBase_->*pointerToComputeFoo_(aValue);
      //else there is nothing to call or some default function.
    };

    //OPTION 2: have a pure virtual protected function to do everything (run) but the call of the double-taking function:
    virtual void run_OPTION2() = 0;
};

class DerivedFooClass: public FooClass
{
  public:
    void run_OPTION1()
    {
      //the user implements its own stuff here.
      //OPTION 1: call the protected base class function:
      ComputeDoubleTakingFunction( doubleValue_ );
      //the user implements its own stuff here too.
    };
  protected:
    //OPTION 2: override the protected virtual function (no need to call compute double-taking function here.
    void run_OPTION2() {
      //the user implements its own stuff only here.
    };
};

Note that the two options should be mutually exclusive (they are not really, but it is better design (semantics) to pick one option only).

Ok, so from what I understand, you need basically the freedom of the generic programming option without using anything "too complicated for the users of your library". In other words, you want to avoid templates, policy classes, even multiple inheritance... essentially anything outside the capabilities of a very novice programmer (who probably should not touch your library anyways, or any other libraries for that matter).

To solve the problem, there is little you can do to mimic generic programming at run-time (not at compile time with templates) without adding overhead (time + memory), but I guess that doesn't matter to you. Building on your code, the simplest solution is abstraction, which can be realized in two different ways here:

class BaseClass; //forward-declaration.

class FooClass
{
  public:
    typedef void ( *pointerToDoubleTakingFunction ) ( double& );
    typedef void ( BaseClass::*pointerToComputeFoo ) ( double& ); //note BaseClass here.
  private:
    pointerToDoubleTakingFunction pointerToDoubleTakingFunction_;
    pointerToComputeFoo pointerToComputeFoo_;
    BaseClass* pointerToBase_; //note: you need a pointer to BaseClass in order to call pointerToComputeFoo_
  public:
    FooClass() : pointerToDoubleTakingFunction_(NULL),
                 pointerToComputeFoo_(NULL), pointerToBase_(NULL) {};

    virtual ~FooClass() {};

    void setDoubleTakingFunction( pointerToDoubleTakingFunction
                                                  pDoubleTakingFunction )
    {
        pointerToDoubleTakingFunction_ = pDoubleTakingFunction;
        pointerToComputeFoo_ = NULL;
        pointerToBase_ = NULL; //note the two options are mutually exclusive.
    };

    void setDoubleTakingFunction( pointerToComputeFoo
                                                  pComputeFoo, BaseClass* pBase )
    {
        pointerToComputeFoo_ = pComputeFoo;
        pointerToBase_ = pBase;
        pointerToDoubleTakingFunction_ = NULL; //again, mutual exclusion.
    };

    void setDouble( double doubleValue )
    {
        doubleValue_ = doubleValue;
    }

    //OPTION 1: as before
    virtual void run_OPTION1() = 0;

    //OPTION 2: implement a public run function that calls a protected virtual run function (see below)
    void run_public_OPTION2() {
      run_OPTION2(); //call virtual function (derived class implementation).
      ComputeDoubleTakingFunction(doubleValue_);
    };

protected:
    
    double doubleValue_;

    //OPTION 1: make a protected function for the derived class to call that abstracts the details of whether it is a global function or member function.
    void ComputeDoubleTakingFunction(double aValue) {
      if(pointerToDoubleTakingFunction_)
        pointerToDoubleTakingFunction_(aValue);
      else if((pointerToComputeFoo_) && (pointerToBase_))
        pointerToBase_->*pointerToComputeFoo_(aValue);
      //else there is nothing to call or some default function.
    };

    //OPTION 2: have a pure virtual protected function to do everything (run) but the call of the double-taking function:
    virtual void run_OPTION2() = 0;
};

class DerivedFooClass: public FooClass
{
  public:
    void run_OPTION1()
    {
      //the user implements its own stuff here.
      //OPTION 1: call the protected base class function:
      ComputeDoubleTakingFunction( doubleValue_ );
      //the user implements its own stuff here too.
    };
  protected:
    //OPTION 2: override the protected virtual function (no need to call compute double-taking function here.
    void run_OPTION2() {
      //the user implements its own stuff only here.
    };
};

Note that the two options should be mutually exclusive (they are not really, but it is better design (semantics) to pick one option only).

Thanks for the detailed response. I went ahead and tried your suggestions, and everything seems to work fine, except that the compiler throws this error:

error: must use '.*' or '->*' to call pointer-to-member function in '((FooClass*)this)>FooClass::pointerToComputeFoo_ (...)'

This is linked to the following line of code:

pointerToBase_->*pointerToComputeFoo_(aValue);

I can't seem to get around this, and it's very strange to me, since the error shows that it's in the scope of FooClass that the pointer to member function pointerToComputeFoo_ is compiled, whilst the typedef explicitly places it in the scope of BaseClass.

Something rather funky seems to be happening here.

I hope you can help me sort this out.

Your feedback is much appreciated.

Thanks in advance,

Kartik

Thanks for the detailed response. I went ahead and tried your suggestions, and everything seems to work fine, except that the compiler throws this error:

This is linked to the following line of code:

pointerToBase_->*pointerToComputeFoo_(aValue);

I can't seem to get around this, and it's very strange to me, since the error shows that it's in the scope of FooClass that the pointer to member function pointerToComputeFoo_ is compiled, whilst the typedef explicitly places it in the scope of BaseClass.

Something rather funky seems to be happening here.

I hope you can help me sort this out.

Your feedback is much appreciated.

Thanks in advance,

Kartik

Is it not the same issue of forgetting the ClassName:: *iamAPointer?
Try adding the class in which it is contained

Is it not the same issue of forgetting the ClassName:: *iamAPointer?
Try adding the class in which it is contained

The class name has been added in the typdef:

typedef void ( BaseClass::*pointerToComputeFoo ) ( double& );

That's why I'm puzzled.

Not able to make any sense of it. Any feedback would be appreciated.

Cheers,

Kartik

what is your current code?
I'm not familiar with class forwarding so I'm lost in Mike's code.
Where is BaseClass?

Here is the solution (I guess it has to do with priority of operations, I never had that problem before, but again, I rarely use pointers to member functions):

(pointerToBase_->*pointerToComputeFooFunc_)(aValue); //notice additional parentheses.

Here is the solution (I guess it has to do with priority of operations, I never had that problem before, but again, I rarely use pointers to member functions):

(pointerToBase_->*pointerToComputeFooFunc_)(aValue); //notice additional parentheses.

That makes it compile!

Here is the solution (I guess it has to do with priority of operations, I never had that problem before, but again, I rarely use pointers to member functions):

(pointerToBase_->*pointerToComputeFooFunc_)(aValue); //notice additional parentheses.

That works!

Thanks a lot :)

Just grappling with an inheritance issue now, since there are lots of links between classes in the piece of software I'm writing, and for some reason the compiler is throwing a:

"expected class-name before '{' token"

error. Just have to figure out where I'm going wrong. Have some forward class declarations in place, but I guess maybe something is getting defined doubly somewhere.

I'm gonna stick to this implementation for now until I can get a full handle on the use of functors and templates as an alternative. Eventually, I'm going to try to migrate the architecture in that direction.

Thanks for helping me sort this out :)

Cheers,

Kartik

if you have alot fo inheritance may be you need to consider polymorphism

if you have alot fo inheritance may be you need to consider polymorphism

I have made quite a lot of use of polymorphism, and turning out to be very useful :)

Pretty much have my code working now, however the results are not what I expect; so some more debugging to do to make sure there aren't any silly errors anywhere.

Thanks for all the feedback,

Kartik

I have made quite a lot of use of polymorphism, and turning out to be very useful :)

Pretty much have my code working now, however the results are not what I expect; so some more debugging to do to make sure there aren't any silly errors anywhere.

Thanks for all the feedback,

Kartik

:icon_wink:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.