Pointer on fonction

Excuse to me my inexperience out of C++


I have the class A :

class A
{
public :

A(void * (*fonction)(void *));
~A();

};

Class A is a Thread Class
and I want to use this class with member fonction.

How can I do ?

That’s all I can say… You description was not very detailed :wink:

void *myFonction(void *) // What is a fonction? :wink:
{

}

int main()
{
A myA(myFonction);

return 0;
}

“Tiki” <tiki@caramail.com> wrote in message
news:39FD7A5F.4A64E470@caramail.com

Excuse to me my inexperience out of C++


I have the class A :

class A
{
public :

A(void * (*fonction)(void *));
~A();

};

Class A is a Thread Class
and I want to use this class with member fonction.

How can I do ?

Markus Loffler wrote:

That’s all I can say… You description was not very detailed > :wink:

void *myFonction(void *) // What is a fonction? > :wink:
{

}

int main()
{
A myA(myFonction);

return 0;
}

And, if myFonction() is member of class B

Alright, I understand now.

Member functions are different to normal global functions, because member
functions use the “this” pointer. The only way here is to use a static
function:

class B
{
static void *myFonction(void *); // myFonction is static
}

int main()
{
A myA(B::myFonction);

return 0;
}


But be careful, in static functions, you don’t have the “this” pointer, you
access any members of the class:

class B
{
static void *s_myFonction(void *); // myFonction is static

int test; // some data member
}

void *B::s_myFonction(void *)
{
cout << test << endl; // !!! doesn’t work
}


This problem usually occurs if you want to pass member functions to C API’s
like Photon (e.g., to implement callbacks). You are lucky, if you are able
to pass a pointer to your function (In you case it looks like it - you can
pass a void * to myFonction.

class B
{
static void *s_myFonction(void *); // myFonction is static
void *myFonction(); // Normal class member

int test; // some data member
}

void *B::s_myFonction(void *data)
{
((B *) data)->myFonction(); // Assuming that you passed “this” as
data
}

void *B::myFonction ()
{
cout << test << endl; // Now you can access data members
}

Hope that helps
Markus




“Tiki” <tiki@caramail.com> wrote in message
news:39FDBD36.C2274F86@caramail.com

Markus Loffler wrote:

That’s all I can say… You description was not very detailed > :wink:

void *myFonction(void *) // What is a fonction? > :wink:
{

}

int main()
{
A myA(myFonction);

return 0;
}



And, if myFonction() is member of class B

In article <39FD7A5F.4A64E470@caramail.com>, Tiki <tiki@caramail.com> wrote:

Excuse to me my inexperience out of C++


I have the class A :

class A
{
public :

A(void * (*fonction)(void *));
~A();

};

Class A is a Thread Class
and I want to use this class with member fonction.

How can I do ?

I know an answer was given, but this is sort of a FAQ, and
it isn’t necessary to use a static member function
all the time. You can have a cleaner class design if you
use a functor pattern and implement functors with template.
In short a functor is an object that looks like a pointer
to a function, but carries both the function pointer and
the target object. It is type-safe, so it doesn’t break
between compiler implementations – which does happen if
you try to down-cast member function pointers.

At the end of this post, I have a complete example of functors.
Here’s a column I wrote on callback functors several years ago for
the X Journal:



Generalized Callbacks for C++



In several of my previous columns I have advocated a strong separation
between the user interface and the application logic within an
application. This is crucial to supporting a single application on
several platforms, but its utility is also evident when an application
is supported on a single logical platform but requirements dictate a
tailoring of the user interface to different environments or users.

Consider for example a web browser written to a virtual toolkit that
must run on a television set-top box, a PC or a high-end workstation.
The widely varying capabilities of the display devices may necessitate
the presentation of a completely different interface to the user in each
case. Likewise, different user roles or levels of expertise can often
require user interface controls that are tailored to the individual. In
such cases, it is often better to have multiple user interfaces that
access reusable components implementing the underlying application
functionality.

This can present some unique difficulties to developers using C++
because of its combination of strong, static typing with object-oriented
programming. Conventional means of integrating the application code with
the user interface often impose an inheritance relationship on one or
both of the objects, resulting in an intrusion on the class hierarchy of
application objects, thereby limiting their reusability, or forcing the
developer to subclass new auxiliary classes from both classes to
complete the binding – which results in a significant increase in the
amount of source code required.

Often in these cases, the programmer simply wanted the equivalent of an
Xt callback that would allow a member function of the C++ object to be
invoked from within the callback. With this in mind, I am going to
present a model for C++ callbacks that is closer to the conventional Xt
model than others I have seen advocated in the Motif FAQ or other
literature. Since it is completely self-contained, it is also a useful
idiom in general for allowing two objects to invoke each other’s methods
without any knowledge about the type of the other object.

Conventional Callback Approaches



One approach that is commonly used, especially in cases where widget
wrappers or a virtual toolkit is used, is to provide a virtual function
for the widget class corresponding to each callback supported by the
widget. The wrapper assumes responsibility for ensuring that the virtual
function is called on the correct object, and the implementation of this
is hidden from the programmer.

For example the toolkit would have a PushButton class that provides
Arm(), Activate() and Disarm() callbacks as in the following elided code
fragment:


class PushButton
{

protected:
virtual void Arm(XmPushButtonCallbackStruct *cbs);
virtual void Activate(XmPushButtonCallbackStruct *cbs);
virtual void Disarm(XmPushButtonCallbackStruct *cbs);
};



To modify the behaviour of the PushButton, you must subclass from it to
override any of the callback functions. In most cases, the actual work
won’t be done by the specialized push button itself. It has to delegate
the function to its parent or another object that has access to the
necessary data or application knowledge to carry out the operation.

For example, consider a form or dialog. Any dialog will require an
“okay” button to confirm that the dialog is complete and processing can
take place on the form data. The button itself doesn’t have access to
the form data, so it must notify the form object that the user has given
confirmation and it should proceed to process the information. To do
this, the specialized button has to have a pointer to the form and it
must know the type of the form or the ancestor that provides the
appropriate confirmation method.

So now we have something like this:


class Form {

public:
virtual void confirm(void);
};

class MyForm {

public:
virtual void confirm(void);
};

class OkayButton {
public:
virtual void Activate(XmPushButtonCallbackStruct *cbs);

create(Form *form);
};

OkayButton::Activate(XmPushButtonCallbackStruct *cbs)
{
form->confirm();
}



The form is responsible for creating the OkayButton object and
initializing its pointer to the form so that it can be called back
later. This technique is obviously verbose and although techniques can
be employed to maximize reuse of specialized widgets, it requires great
care on the part of the programmer to coordinate communication between
widgets and the components that hold them. Consequently it also becomes
very difficult to alter these relationships because all of the dependent
classes must be changed as well.

Another drawback to this approach is that it doesn’t encourage dynamic
changes to the behaviour in response to the button press that may be
controlled by the higher-level object (i.e. the form).

A second commonly used technique places responsibility for registering
and responding to the Xt callbacks themselves on the class that
implements the C++ member function. This is usually the class that also
creates the widgets, in our case being the form class. This class must
provide two functions for each callback: a static member function for
the Xt callback, and the corresponding member function. When it is
invoked, the static member function must obtain the this pointer to the
object and use it to call the corresponding member function.

The pointer to this is usually stored in the client_data for the Xt
callback. The static member function casts the client_data value into a
pointer to the object, casts the call_data to the appropriate callback
structure if necessary, and then calls the member function using these
values.

Using this technique, the form example above would now look something
like this:


class MyForm {

public:
Widget button;
void create_widgets(void);
void confirm(XmPushButtonCallbackStruct *);
static void confirm_cb(Widget, XtPointer, XtPointer);

};

void MyForm::create_widgets(void)
{

button = XmCreatePushButton(…);
XtAddCallback(w, XmNactivateCallback, &MyForm::confirm_cb,
(XtPointer) this);

}

void MyForm::confirm_cb(Widget w, XtPointer client_data, XtPointer call_data)
{
MyForm *form = (MyForm *)client_data;
XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;

form->confirm(cbs);
}



This technique requires fewer classes than the preceding one and is
therefore better encapsulated, but there is still some proliferation of
source code evident in that the technique requires both a static member
function and a member function for every callback provided. One
advantage to this technique over the other, though, is that much of the
work can readily be hidden through the use of macros for declaring and
implementing the pair of member functions for implementing the callback.
It would be simpler, however, if the callback could simply be treated as
a single object.

Callbacks as Functors



The bulk of the problem in this situation is precisely this. A pointer
to a C function can be treated as a single object, whereas a C++ member
function requires both the pointer to the object and the pointer to the
member function to be of use. If both pointers are encapsulated within
an object, however, then the callback can be treated as a first-class
object; it can be created, passed as a parameter or otherwise
manipulated like any other object.

This type of object is referred to as a functor and the concept is
covered in the book “Advanced C++: Programming Styles and Idioms” by
James Coplein. Coplein describes a functor as a function that behaves
like an object, with a single member function that provides the function
definition. The functor idiom is advocated “whenever you would otherwise
be tempted to use function pointers, particularly member function
pointers”.

We can now encapsulate the use of a push-button callback as in the
example given below. As you can see, the callback is invoked using
normal function call syntax, and created by the form with a simple
constructor. The functor even provides the Xt callback and installs it
for the client class. The Xt callback for the functor pulls the address
of the functor out of the Xt client_data and invokes its function
definition. This yields a nicer abstraction but it still requires the
same amount of source code, so it hasn’t bought as all that much. In
fact, at first blush our example may even look a little more complicated
than the second example above.


class MyFormPushButtonCB {
MyForm *object;
void (MyForm::*callback)(XmPushButtonCallbackStruct *cbs);

static void xt_callback(Widget, XtPointer, XtPointer);
public:
MyFormPushButtonCB(MyForm *obj,
void (MyForm::*pmf)(XmPushButtonCallbackStruct *))
: object(obj), callback(pmf)
{
}

void install(Widget w, char *cb)
{
XtAddCallback(w, cb, &MyFormPushButtonCB::xt_callback,
(XtPointer) this);
}

void operator () (XmPushButtonCallbackStruct *);
};

static void
MyFormPushButtonCB::xt_callback(Widget w, XtPointer client_data, XtPointer call_data)
{
MyFormPushButtonCB *cb = (MyFormPushButtonCB *)client_data;
XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;

(*cb)(cbs);
}

void
MyFormPushButtonCB::operator () (XmPushButtonCallbackStruct *cbs)
{
if (object && callback)
(object->*callback)(cbs);
}



The real advantage here is that by using a class, we can take advantage
of inheritance to factor out common code. The only parts of the above
class that are specific to the form class are the types of the two
pointers and the dereference operation on the member function pointer.
The rest of the behaviour can be encapsulated in an abstract base class
that can be used for all push-button callbacks.

We can now define the base class for push-button callbacks this way:


class PushButtonCB_base {
static void xt_callback(Widget, XtPointer, XtPointer);
public:
void install(Widget, char *);
virtual void operator () (XmPushButtonCallbackStruct *) = 0;
};

void
PushButtonCB_base::install(Widget w, char *cb)
{
XtAddCallback(w, cb, &PushButtonCB_base::xt_callback,
(XtPointer) this);
}

static void
PushButtonCB_base::
xt_callback(Widget w, XtPointer client_data, XtPointer call_data)
{
PushButtonCB *cb = (PushButtonCB *)client_data;
XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;

(*cb)(cbs);
}



Now to create a callback that’s specific to the form class, we just have
to create a derived class that provides a constructor and the function
call operator, and keeps track of our two pointers. The only purpose
served by the derived class is to maintain type information and
dereference the pointers.

Callback Templates



Since any class derived from the base callback class just needs to
supply the type information for the object and member function pointers,
it is a perfect candidate for a class template. We can now define a
template that automatically instantiates the derived class for us for
push-button callbacks:


template class PushButtonCB : public virtual PushButtonCB_base {
T *object;
void (T::*callback)(XmPushButtonCallbackStruct *cbs);
public:
PushButtonCB(T *obj, void (T::*pmf)(XmPushButtonCallbackStruct *cbs)
: object(obj), callback(pmf) {};

void operator () (XmPushButtonCallbackStruct *cbs)
{
if (object && callback)
(object->*callback)(cbs);
}
};



The template now provides a very simple mechanism for GUI objects to
bind Xt callbacks to their own member functions. Our previous form
example now becomes:


class MyForm {

public:
Widget button;
PushButtonCB *cb;

void create_widgets(void);
void confirm(XmPushButtonCallbackStruct *);

};

void MyForm::create_widgets(void)
{

cb = new PushButtonCB(this, &MyForm::confirm);
button = XmCreatePushButton(…);
cb->install(w, XmNactivateCallback);

}



It is very easy to create abstract base classes for all of the callback
types supported by Motif. The only difference between each of these is
the type signature of the member function to be called, so the same code
can be used with only slight modification.

You can also create generic callbacks based on the same model. Again,
the defining factor that characterizes the callback is the type
signature used for calling the member function. You just have to create
a base class and a corresponding template for each form of argument list
you will support.

Conclusion



Taken together, functors and templates form the ideal mechanism for
providing callbacks in C++. This allows you to provide an
object-oriented callback facility for all of the callback mechanisms in
Motif and Xt (callbacks, actions, timer procs, etc.). It also creates a
means where any object can control how it, or a subordinate object, gets
used by another object without requiring the object to have any
foreknowledge about the service it’s using, thus maximizing your
flexibility in decoupling the different parts of your application. //www.altavista.digital.com/cgi-bin/query?pg=q&what=web&stq=20&fmt=.&q=parse+grammar


Functor Example (functors.C):



#include <iostream.h>

// Implements Callback/Closure as a functor

class VFunctorV_Base
{
protected:
virtual void invoke(void) = 0;

public:
void operator () (void) { invoke(); }
};

template class VFunctorV : public virtual VFunctorV_Base
{
T *obj;
void (T::*pmf)(void);
public:

VFunctorV( T *o = NULL, void (T::*f)(void) = NULL )
: obj( o ), pmf( f )
{
}

virtual void invoke( void )
{
if ( obj && pmf )
(obj->*pmf)();
}
};

class A
{
virtual void Trigger(void) = 0;
};

class B : public A
{
int a;
public:

B(int x) : a(x) {};

void Trigger(void);
};

class C : public A
{
int a;
int b;
public:
C(int x, int y) : a(x), b(y) {};

void Trigger(void);
};

class D
{
const char * const msg;
public:
D(const char * const m) : msg(m) {};

void SomeFunc(void);
};

void B::Trigger(void)
{
cout << “Called B::Trigger” << endl;
cout << " state = " << a << endl;
}

void C::Trigger(void)
{
cout << “Called C::Trigger” << endl;
cout << " state = " << a << ", " << b << endl;
}

void D::SomeFunc(void)
{
cout << “Called D::Trigger” << endl;
cout << " state = " << msg << endl;
}

class UI
{
VFunctorV_Base *callbacks[10];
int ncallbacks;

public:
UI(void) : ncallbacks(0) {};

int add_callback( VFunctorV_Base *cb );
void trigger_callbacks(void);
};


int
UI::add_callback(VFunctorV_Base *cb)
{
int ret = 0;

if ( cb && ncallbacks < 10 )
{
callbacks[ncallbacks++] = cb;
}
else
{
ret = cb ? 1 : 2;
}

return ret;
}

void
UI::trigger_callbacks(void)
{
for (int i = 0; i < ncallbacks; i++)
{
VFunctorV_Base *function = callbacks_;
(*function)();
}
}

main(int argc, char **argv)
{
UI ui;

B b(10);
C c(20,30);
D d(“hello world”);

VFunctorV bf( &b, &B::Trigger);
VFunctorV cf( &c, &C::Trigger);
VFunctorV df( &d, &D::SomeFunc);

(void) ui.add_callback( &bf );
(void) ui.add_callback( &cf );
(void) ui.add_callback( &df );

ui.trigger_callbacks();
}


Steve Furr email: furr@qnx.com
QNX Software Systems, Ltd._