Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Passing a Class member function as a Callback function

Posted on 1999-07-15
11
Medium Priority
?
367 Views
Last Modified: 2010-04-02
Hi
A class I wrote gets a callback function pointer in it's
constructor, and saves it to inform it's creator that
something happned.
Now, when creating an instance of it I need to pass it
a member function of the instance of another class who
creates it.
I keep getting a typecast error message saying It can't
find a matching function in the overloaded functions
with this name.
I only have one function with that name, but it's not
static, so it refuses to accept it.

typedef void (*CallbackFuncType)();

class A
{
   A(int a, int b, CallbackFuncType CallbackFunc};
}

class B
{
   A* m_pA;

   void cb() {...};

   int something()
   {
     m_pA = new A(x, y, (CallbackFuncType)cb);
   }
}        

error C2440: 'type cast' : cannot convert from 'overloaded function type' to 'void (__stdcall *)(void)'
None of the functions with this name in scope match the target type
0
Comment
Question by:giln
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
11 Comments
 

Author Comment

by:giln
ID: 1200161
Edited text of question.
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 1200162
The typedef is wrong, for member functions you need to pass in the class type to (remember methods take an implicit this pointer),

so you should have:

typedef void (B::*CallbackFuncType)();

to call it, you need to do:

(m_pA->*cb)();




0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 1200163
Oh, this won't quite work for you you will need to pass in a pointer to the object into class A together with the constructor, so the A should look like:

typedef void (B::*CallbackFuncType)();

class A
{
public:
   A(int a, int b, B* theb, CallbackFuncType cb};
   void CallIt() { (theb->*cb)(); }
}

This doesn't help if you want to pass callback functions from any class into A.  I can show you away around this that makes the cb function type into a templated class to solve the problem.



0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:giln
ID: 1200164
The whole idea is I need to avoid from class
A knowing class B,
If this is the only solution, it doesn't help me
since in such case I will hold a pointer to B,
and implicitly call the function.
0
 

Author Comment

by:giln
ID: 1200165
The whole idea is I need to avoid from class
A knowing class B,
If this is the only solution, it doesn't help me
since in such case I will hold a pointer to B,
and implicitly call the function.
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 1200166
You can use something like the following then:

class AbstractCallback {
public:
    virtual void operator()() = 0;
};

template <class T>
class SimpleCallback : public AbstractCallback  
{
public:
    typedef void (T::*CB)();

    SimpleCallback(T* instance, CB callback)
        : mInstance(instance), mCallback(callback)
{}

    virtual ~SimpleCallback() {}

    virtual void operator()() {
        (mInstance->*mCallback)();
    }
protected:
    T* mInstance;
    CB mCallback;
};

class A
{
public:
    A(int a, int b, AbstractCallback* cb)
        : mCb(cb),  //...

    virtual ~A() { delete mCb; }

    void CallFunction() {
        (*mCb)();
    }
private:
    AbstractCallback* mCb;
};

class B
{
public:
     void CallbackFunc() { }
     int something()
     {
         m_pA = new A(x, y, new SimpleCallback<A>(this, CallbackFunc); );
     }
};




0
 

Author Comment

by:giln
ID: 1200167
Answer so I can credit you
0
 
LVL 9

Accepted Solution

by:
jasonclarke earned 200 total points
ID: 1200168
thanks.
0
 

Author Comment

by:giln
ID: 1200169
Small correction : ***

class B
{
public:
     void CallbackFunc() { }
     int something()
     {
         m_pA = new A(x, y, new SimpleCallback<B>(this, CallbackFunc); );
     }
};

0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 1200170
Yes, sorry about that.

You note that the receiver of the callback takes responsibility for deleting the it.  This does not have to be the case, but you should be aware that if it does, you must create a new instance of the SimpleCallback every time you set a callback.

And since the object must be created on the heap, you probably should change SimpleCallback to look like:

template <class T>
class SimpleCallback : public AbstractCallback    
{
public:
    typedef void (T::*CB)();

    SimpleCallback* Create(T* instance, CB callback)
    { return new SimpleCallback<T>(instance, callback) };

    virtual ~SimpleCallback() {}

    virtual void operator()() {
        (mInstance->*mCallback)();
    }
protected:
    SimpleCallback(T* instance, CB callback)
        : mInstance(instance), mCallback(callback)
    {}

    T* mInstance;
    CB mCallback;
};




0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 1200171
the Create function should have been static!
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question