Pointer to a function member.

G

Guy Dreger

Hi, I have read a lot of solutions to this problem but I can't help but
think I'm missing a better answer.

I have a class called UI. That handles all the User Interface stuff for
some dedicated hardware (forklifts and such). The UI class is used in
lots of different applications that do different things. I would like
to offer in the UI a way of handling the validation of in coming
characters. This is down quite low down in the code and in C I would
simply create a pointer function and a function to set the pointer
function so the low level code knows to use it. This of course all
still works with a straight C main line but when the UI class is used
inside a different class I loss the ability to set the call back
function to a function member.

Complicating matters is that many apps are highly multi-threaded. i.e.
handling many forklifts/users and what they are doing all at once so
static members are not much of a help.

Also;
[soap-box mode on]
Why is this such a problem for the compiler manufactures? I normally
get the response that they need the instance information. Of course.
This is a Duh.... But They have it. They have the class deceleration,
the function (and therefore the function offset from the class
instance), The this pointer. As I see it everything is available to
them. I'd be willing to conceded they may want different syntax in
order to make member functions and standard c functions easier to
distinguish and handle. So the question here is.... Whats up with that ah?
[soap-box mode off]
 
V

Vaclav Haisman

Guy Dreger wrote, On 10.7.2009 19:21:
Hi, I have read a lot of solutions to this problem but I can't help but
think I'm missing a better answer.

I have a class called UI. That handles all the User Interface stuff for
some dedicated hardware (forklifts and such). The UI class is used in
lots of different applications that do different things. I would like
to offer in the UI a way of handling the validation of in coming
characters. This is down quite low down in the code and in C I would
simply create a pointer function and a function to set the pointer
function so the low level code knows to use it. This of course all
still works with a straight C main line but when the UI class is used
inside a different class I loss the ability to set the call back
function to a function member.

Complicating matters is that many apps are highly multi-threaded. i.e.
handling many forklifts/users and what they are doing all at once so
static members are not much of a help.
As long as your callback functions can have at least a single parameter
through wich you can identify UI class instance, I do not see any problem. If
you are thinking about getting address/pointer to member function that is
bound to some instance, well, that is supported only as extension by few
compilers.
Also;
[soap-box mode on]
Why is this such a problem for the compiler manufactures? I normally
get the response that they need the instance information. Of course.
This is a Duh.... But They have it. They have the class deceleration,
the function (and therefore the function offset from the class
instance), The this pointer. As I see it everything is available to
them. I'd be willing to conceded they may want different syntax in
order to make member functions and standard c functions easier to
distinguish and handle. So the question here is.... Whats up with that ah?
What's up with what? Your whole post is rather vague.
[soap-box mode off]
 
G

Guy Dreger

Here is an example of what I mean.

In Test.C this works. i.e. a c main line using a class.

Int MyChecker(int TheChar)
{
// bla. Bla bla
return(GOODorBAD);
}

Main()
{
class UI ui;
ui.SetCallBack(&MyChecker);
// bla. Bla bla
exit(0);
}






In Text.CPP this does not work.

Class FL {
class UI ui;

Int MyChecker(int TheChar) ;
int Go(void);

}

Int FL:MyChecker(int TheChar)
{
bla. Bla bla
return(GOODorBAD);
}

int FL:Go(void)
{
ui.SetCallBack(&MyChecker);
// or ui.SetCallBack(&his->MyChecker);
// or what ever.
}

Main()
{
class FL fl.
fl.Go();
exit(0);
}







Trouble is FL is not the only class I use UI in.
I also use it in LI, PUTS, etc...

so how do I declare SetCallBack in the UI class to be able to take
functions from just about any class that UI is being used in.

for that matter how do I create the function pointer. In C I would do this.

int (*TheCallBackFunction)(int CharToCheck);
but it seems c++ wants this;

int (FL::*TheCallBackFunction)(int CharToCheck);
so, again trouble is FL is unknown at the time of compiling UI.cpp.
It could be FL or LI or PUTS or any number of other applications I used
UI in.

I have also had suggestion to use a third party lib (i.e. Boost) but
that in itself has some political hurdles for me.


Also;
[soap-box mode on]
Why is this such a problem for the compiler manufactures? I normally
get the response that they need the instance information. Of course.
This is a Duh.... But They have it. They have the class deceleration,
the function (and therefore the function offset from the class
instance), The this pointer. As I see it everything is available to
them. I'd be willing to conceded they may want different syntax in
order to make member functions and standard c functions easier to
distinguish and handle. So the question here is.... Whats up with that ah?
What's up with what? Your whole post is rather vague.
[soap-box mode off]
 
S

sebastian

It has nothing to do with the compiler manufacturers. What you're
wanting to do is just not part of the language. It's as simple as
that. You can possibly go with some compiler extension but then you
you've just locked yourself into a certain vendor by writing non-
portable code.

Anyway, the best way to do this is probably to define a base class
with a virtual function that takes an int parameter, and then subclass
it with a template class that actually stores the member function and
object pointers, overriding the virtual function to call the member
function. The UI class would declare a shared pointer or what have you
to the base class, and when SetCallback is invoked it assigns the
pointer to a new Derived<User>(ptr, &User::function).

An even simpler way (but it is sort of a hack, and I'm not sure it
would be safe for classes using multiple inheritance) would be
something like this:

class UI
{
public:

UI( void )
: user( 0 ), callback( 0 )
{ }

class User
{
public:

typedef int ( User:: *callback_function )( int );
};

template < typename Derived >
void SetCallback( User* self, int ( Derived:: *function )( int ) )
{
user = self;
callback = User::callback_function( function );
}

void check( int value )
{
( user->*callback )( value );
}

User* user;
User::callback_function callback;
};

class FL : public UI::User
{
public:

UI ui;

FL( void )
{
ui.SetCallback( this, &FL::MyChecker );
}

int MyChecker( int value )
{
std::cout << "FL::MyChecker( " << char( value ) << " ) " <<
std::endl;
}
};

class LI : public UI::User
{
public:

UI ui;

LI( void )
{
ui.SetCallback( this, &LI::DoCheck );
}

int DoCheck( int value )
{
std::cout << "LI::DoCheck( " << char( value ) << " ) " << std::endl;
}
};

int main( void )
{
FL fl;
LI li;
fl.ui.check( 'S' );
li.ui.check( 'G' );
}
 
P

Paul Brettschneider

Guy said:
Here is an example of what I mean.

In Test.C this works. i.e. a c main line using a class.

Int MyChecker(int TheChar)
{
// bla. Bla bla
return(GOODorBAD);
}

Main()
{
class UI ui;
ui.SetCallBack(&MyChecker);
// bla. Bla bla
exit(0);
}

[empty lines removed...]

In Text.CPP this does not work.

Class FL {
class UI ui;

Int MyChecker(int TheChar) ;
int Go(void);

}

Int FL:MyChecker(int TheChar)
{
bla. Bla bla
return(GOODorBAD);
}

int FL:Go(void)
{
ui.SetCallBack(&MyChecker);
// or ui.SetCallBack(&his->MyChecker);
// or what ever.
}

Main()
{
class FL fl.
fl.Go();
exit(0);
}

[...empty lines removed...]

Trouble is FL is not the only class I use UI in.
I also use it in LI, PUTS, etc...

so how do I declare SetCallBack in the UI class to be able to take
functions from just about any class that UI is being used in.

You don't. User virtual (and multiple) inheritance, that's what it's there
for. Let your FL classes derive from a pure virtual "Checker" class and
implement the "MyCheck" method. Just pass the this pointer to the UI class,
which takes a pointer/reference to the "Checker" class and calls the MyCheck
method. Simple and much easier to read/understand.
 
G

Guy Dreger

Sorry, Low on the OO Lingo.

Are you suggesting the same kind of thing sebastian outlined?

I goto tell you. if sebastians outline will work for me then... Fine.
But if there is a better (smaller) solution that would be great too.


Paul said:
Guy said:
Here is an example of what I mean.

In Test.C this works. i.e. a c main line using a class.

Int MyChecker(int TheChar)
{
// bla. Bla bla
return(GOODorBAD);
}

Main()
{
class UI ui;
ui.SetCallBack(&MyChecker);
// bla. Bla bla
exit(0);
}

[empty lines removed...]

In Text.CPP this does not work.

Class FL {
class UI ui;

Int MyChecker(int TheChar) ;
int Go(void);

}

Int FL:MyChecker(int TheChar)
{
bla. Bla bla
return(GOODorBAD);
}

int FL:Go(void)
{
ui.SetCallBack(&MyChecker);
// or ui.SetCallBack(&his->MyChecker);
// or what ever.
}

Main()
{
class FL fl.
fl.Go();
exit(0);
}

[...empty lines removed...]

Trouble is FL is not the only class I use UI in.
I also use it in LI, PUTS, etc...

so how do I declare SetCallBack in the UI class to be able to take
functions from just about any class that UI is being used in.

You don't. User virtual (and multiple) inheritance, that's what it's there
for. Let your FL classes derive from a pure virtual "Checker" class and
implement the "MyCheck" method. Just pass the this pointer to the UI class,
which takes a pointer/reference to the "Checker" class and calls the MyCheck
method. Simple and much easier to read/understand.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top