C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to call a member function of any class

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Kurt Stege
Guest





PostPosted: Tue Apr 20, 2004 10:35 pm    Post subject: How to call a member function of any class Reply with quote



Hello to all.

(First, my goals, and than some questions how to arrive...)

For the sake of reusable source code I would like to
encourage developers (that is my colleages) to develop
in terms of "components", and to create applications
by loosely connect these components.

Here a rough sketch for two components A and B:

class A
{
signal s1(int p1, long p2, double p3);
// and additional stuff for component A
}

class B
{
slot s2(int p1, long p2, double p3);
// and additional stuff
}

The component A does its work and may sometimes emit
the signal s1. Component B has a slot s2, that may be
called from out of the class (I omitted the word public
in my sketch) and implements this slot to do a task
appropriate for B.

A signal may be implemented as a template class that
generates a pointer to a slot (or a list of slots),
and a slot may be either a template class observer,
or a simple member function (as read by "typedef void slot;").

An application could create one instance of A, another
object of type B, and connect s1 with s2, so that emitting
s1 is calling s2.

In this way, A does not know anything of class B, and
vice versa. Connected components just have to be
agreed for the signature of the functions (and the
semantics, of course).

This far, this is a well known signal slot concept, and
already implemented by different libraries. I know about
the boost library, QT, and Sarah Thompsons sigslot library
([url]http://sigslot.sourceforge.net/)[/url].

All these libraries in common is, that they do much more
than I need, and therefore introduce complexity, that is
bothering in debugging, and in memory and run-time usage.

I just need static objects and static connections for
static applications. And even more, I usually have only
one receiver for each signal. Most of our applications
are running in embedded systems, and I would like to
encourage the developers to use components even for
small and simple tasks. For a better acceptance it is
necessary to have only small overhead by using a signal
slot connection instead of a direct functioncall, and
only a small overhead when stepping through such a
call with the debugger.


My idea is:
- make a slot a normal member function without any magic.
- make a signal (using a simple template class) a pointer
to any member function (and store the pointer to the
destination object as well).
To create a connection, the application would store the
destination object and its slot member function in the
signal of the sender. (When in some cases a signal is
connected to several slots simultaneously, I would
create a dispatcher "component" that has a single slot
that calls all the connected receivers. I plan to use
code generation tools to create these helper components
and the connections itself.)

Alas, class A does not know at compile time, what type
the receiver has. Even more, it should be possible to
create two objects of type A, and connect one to an object
of type B, and the other to a type C. Class A does only
know the exact signature of the member function, but
not the class it belongs to.


As far as I have understood the pointer to member functions
in C++, they are only useful when there is a single class
with several different member functions (of same signature),
but not applicable when I have multiple classes with typically
only one function of a given signature.

For this, I could create a base class with a virtual function
for each signature I use and let the component class derive
from this class for each slot.

Alas, this does only work, when a component has for each
signature at most one slot. I don't like this restriction,
and (for documentationary reasons) I would like to give the
slots names in addition to its signature.



Pointer to static functions in C++ are uses as follows:

void foo(int a);
typedef void (*pfoo) (int a);
pfoo p = &foo;

Pointer to "concrete" member functions in C++ are used
as follows ("concrete" for there is a class C given):

class C { void foo(int a); };
typedef void (C::*pfoo) (int a);
C c;
pfoo p = &(c.foo);
c->*p(42);

p just stores the "address" of the member function, but
not the address of the given object C. So I have to store
the address of c in addition, when I want to call c.foo()
later on. (And I could store the member function without
having an actual object: p = &(C::foo);

I would expect a means in C++ to store "abstract" member
functions as well ("abstract" for "valid with any class").

class C { void foo(int a); };
typedef void (::*pfoo) (int a);
C c;
pfoo p = &(c.foo);
p(42);

p should store both the physical address of the member
function (as in a typical compiler implementation in the
vtable), and an "generic" "typeless" object pointer that
may be passed as the this-parameter for that function.
In that way it would be possible to call the specified
member function of exactly that one object at any time
later.


I assume, C++ does not have such a feature, and I guess,
it is not possible using standard (portable) code to
emulate this behaviour? That is a pity, for this is
exactly what I would like to have in my scenarios.



My current strategie is to store a pointer to a static
function in the signal. For each connection I implement
a global function that calls the (or all) connected slots,
and store this dispatcher function within the signal.

This isn't really elegant, and has some further disadvantages.
But at least, it works, and I don't have any dynamic
behaviour for my static applications, which I see as a
desirable property for embedded systems.


Any ideas, suggestions?

Thanks a lot,
Kurt.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Michiel Salters
Guest





PostPosted: Wed Apr 21, 2004 3:46 pm    Post subject: Re: How to call a member function of any class Reply with quote



Kurt Stege <kstege (AT) innovative-systems (DOT) de> wrote

Quote:
Hello to all.

(First, my goals, and than some questions how to arrive...)

For the sake of reusable source code I would like to
encourage developers (that is my colleages) to develop
in terms of "components", and to create applications
by loosely connect these components.

Here a rough sketch for two components A and B:

class A
{
signal s1(int p1, long p2, double p3);
// and additional stuff for component A
}

class B
{
slot s2(int p1, long p2, double p3);
// and additional stuff
}
[...]
This far, this is a well known signal slot concept, and
already implemented by different libraries. I know about
the boost library, QT, and Sarah Thompsons sigslot library
([url]http://sigslot.sourceforge.net/)[/url].

All these libraries in common is, that they do much more
than I need, and therefore introduce complexity, that is
bothering in debugging, and in memory and run-time usage.

I just need static objects and static connections for
static applications.

You could of course use boost::function/boost::bind

I.e.

#include "B.h"
class A {
public:
boost::function s1<void(int,long,double)>; // No B here
};

A a;
B b;
a.s1 = boost::bind( &B::s2, b, _1, _2, _3 );
a.s1( 1, 1L, 1.0 ); // Calls b.s2( 1,1L,1.0 );

You can even connect signals to slots with more arguments,
by fixing the extra arguments at bind time. Just replace
an _<n> placeholder with a constant.

Regards,
Michiel Salters

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bill Weston
Guest





PostPosted: Sat Apr 24, 2004 8:44 pm    Post subject: Re: How to call a member function of any class Reply with quote



[email]Michiel.Salters (AT) logicacmg (DOT) com[/email] (Michiel Salters) wrote in message news:<fcaee77e.0404210047.266f1932 (AT) posting (DOT) google.com>...
Quote:
Kurt Stege <kstege (AT) innovative-systems (DOT) de> wrote

Hello to all.

(First, my goals, and than some questions how to arrive...)

For the sake of reusable source code I would like to
encourage developers (that is my colleages) to develop
in terms of "components", and to create applications
by loosely connect these components.

Here a rough sketch for two components A and B:

class A
{
signal s1(int p1, long p2, double p3);
// and additional stuff for component A
}

class B
{
slot s2(int p1, long p2, double p3);
// and additional stuff
}
[...]
This far, this is a well known signal slot concept, and
already implemented by different libraries. I know about
the boost library, QT, and Sarah Thompsons sigslot library
([url]http://sigslot.sourceforge.net/)[/url].

All these libraries in common is, that they do much more
than I need, and therefore introduce complexity, that is
bothering in debugging, and in memory and run-time usage.

I just need static objects and static connections for
static applications.

You could of course use boost::function/boost::bind

I.e.

#include "B.h"
class A {
public:
boost::function s1<void(int,long,double)>; // No B here
};

A a;
B b;
a.s1 = boost::bind( &B::s2, b, _1, _2, _3 );
a.s1( 1, 1L, 1.0 ); // Calls b.s2( 1,1L,1.0 );

You can even connect signals to slots with more arguments,
by fixing the extra arguments at bind time. Just replace
an _<n> placeholder with a constant.

What happens when b dies?

Bill Weston

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.