473,395 Members | 1,454 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Calling upwards from within an aggregation

If I have two classes:

class bar
{
public:
void RunTheBar(void);
};

class foo
{
private:
bar bar_;
public:
void Callback(void);
void RunTheBar(void){bar_.RunTheBar();}
...
};

What's the best way to design "bar" such that it can call
foo::Callback()
from within its RunTheBar() method?

This is pretty straightforward using the Borland C++Builder extension
"__closure":

typedef void (__closure *MyCallback)(void);

class bar
{
private:
MyCallback callback_;
public:
bar(void):callback_(0){}
void RunTheBar(void);
void SetCallback(MyCallback Acallback){callback_ = Acallback;}
};

void bar::RunTheBar(void)
{
// ...
if (callback_)
{
callback_();
}
// ...
}

class foo
{
private:
bar bar_;
public:
foo(void)
{
bar_.SetCallback(Callback);
}
void Callback(void);
void RunTheBar(void){bar_.RunTheBar();}
};

Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be nice
if "bar" could be contained by objects other than "foo" without needing
to change it each time.

--
Simon Elliott
http://www.ctsn.co.uk/


Jul 19 '05 #1
10 2545
Simon Elliott wrote:
Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be
nice if "bar" could be contained by objects other than "foo" without
needing to change it each time.


Did you look at boost::function?

--
Attila aka WW
Jul 19 '05 #2
On Fri, 26 Sep 2003 11:39:47 +0100, Simon Elliott
<si***@nospam.demon.co.uk> wrote:
If I have two classes:

class bar
{
public:
void RunTheBar(void);
};

class foo
{
private:
bar bar_;
public:
void Callback(void);
void RunTheBar(void){bar_.RunTheBar();}
...
};

What's the best way to design "bar" such that it can call
foo::Callback()
from within its RunTheBar() method?

This is pretty straightforward using the Borland C++Builder extension
"__closure":

typedef void (__closure *MyCallback)(void);
Hmm, I think GCC has something like this too.

class bar
{
private:
MyCallback callback_;
public:
bar(void):callback_(0){}
void RunTheBar(void);
void SetCallback(MyCallback Acallback){callback_ = Acallback;}
};

void bar::RunTheBar(void)
{
// ...
if (callback_)
{
callback_();
}
// ...
}

class foo
{
private:
bar bar_;
public:
foo(void)
{
bar_.SetCallback(Callback);
}
void Callback(void);
void RunTheBar(void){bar_.RunTheBar();}
};

Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be nice
if "bar" could be contained by objects other than "foo" without needing
to change it each time.


If you can use 3rd party libraries, then boost.function is what you
want:

#include <boost/function.hpp>
#include <boost/bind.hpp>

class bar
{
public:
typedef boost::function<void()> MyCallback;
bar(void){}
void RunTheBar(void);
void SetCallback(MyCallback Acallback){callback_ = Acallback;}
private:
MyCallback callback_;
};

void bar::RunTheBar(void)
{
// ...
if (!callback_.empty())
{
callback_();
}
// ...
}

class foo
{
private:
bar bar_;
public:
foo(void)
{
bar_.SetCallback(boost::bind(&foo::Callback, this));
}
void Callback(void);
void RunTheBar(void){bar_.RunTheBar();}
};

See www.boost.org.

Tom
Jul 19 '05 #3


Simon Elliott wrote:
[snip]
Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be nice
if "bar" could be contained by objects other than "foo" without needing
to change it each time.


Yep.
Define a class, eg. 'CallbackReceiver'
Every class wishing to use bar has to be derived
from that class. With multiple inheritance you
can add the 'feature' of being a callback receiver
very easily to each and every class.
bar::RunThebar expects a pointer to a CallbeckReceiver
object, which it uses to make the callback:

class CallbackReceiver
{
public:
void Callback() = 0;
};

class bar
{
public:
void RunTheBar( CallbackReceiver* pCalledFrom )
{
...
pCalledFrom->Callback();
...
}
};

class foo : public CallbackReceiver
{
private:
bar bar_;

public:
void Callback();
void RunTheBar()
{
bar_.RunTheBar( this );
}
...
};

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #4
Attila Feher writes
Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be
nice if "bar" could be contained by objects other than "foo" without
needing to change it each time.
Did you look at boost::function?


Thanks for the quick response. I was put off boost::function by this
snippet from the documentation:

<quote>
Member functions

In many systems, callbacks often call to member functions of a
particular object. This is often referred to as "argument binding", and
is beyond the scope of Boost.Function.
</quote>

And the example which follows:

<quote>
struct X {
int foo(int);
};

boost::function2<int, X*, int> f;

f = &X::foo;

X x;
f(&x, 5);
</quote>

When the function f is called, it seems to need an instance of X to be
visible. Even if this could be a forward declaration, it still limits
the lower level class to only being able to call methods of objects of
type X, rather than methods of objects of an arbitrary type.

I've only ever designed one solution to this problem, and it involves
having an ABC which the lower level class calls a virtual method in. The
higher level class then defines a descendent of the ABC which does the
necessary. It's standard, it's flexible, and it works, but it's always
seemed to me that there must be a better and simpler way.
--
Simon Elliott
http://www.ctsn.co.uk/


Jul 19 '05 #5
Simon Elliott wrote:
Attila Feher writes
Is there a way I can do this without using the non standard
__closure, but still without "bar" needing a definition of "foo"?
It would be nice if "bar" could be contained by objects other than
"foo" without needing to change it each time.

Did you look at boost::function?


Thanks for the quick response. I was put off boost::function by this
snippet from the documentation:


See the post by tom_usenet in this thread.

--
Attila aka WW
Jul 19 '05 #6
tom_usenet <to********@hotmail.com> writes
typedef void (__closure *MyCallback)(void);Hmm, I think GCC has something like this too.


There was some talk about something along these lines being introduced
into the standard.
If you can use 3rd party libraries, then boost.function is what you
want:


I can use those bits of boost that are implemented solely in terms of
headers.

[snip]

This seems a nice clean solution. And I like the way that I don't need
to initialise callback_ in bar's constructor.

I use Borland C++ Builder quite a lot. I'd be interested in using this
technique with the C++ form objects which are generated by this tool. I
wonder if boost::bind and boost::function work with these. One day when
Borland get their news server back up and running I'll ask them!

--
Simon Elliott
http://www.ctsn.co.uk/


Jul 19 '05 #7
Karl Heinz Buchegger <kb******@gascad.at> writes
Simon Elliott wrote:

Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be nice
if "bar" could be contained by objects other than "foo" without needing
to change it each time.


Yep.
Define a class, eg. 'CallbackReceiver'
Every class wishing to use bar has to be derived
from that class. With multiple inheritance you
can add the 'feature' of being a callback receiver
very easily to each and every class.
bar::RunThebar expects a pointer to a CallbeckReceiver
object, which it uses to make the callback:


[snip]

Interesting idea, simpler and neater than my own inheritance based
solution.

Sadly it won't work in all the cases I'd like to use. I use Borland C++
Builder quite a lot, and any C++ object which inherits from an Object
Pascal/Delphi object can't use MI.
--
Simon Elliott
http://www.ctsn.co.uk/


Jul 19 '05 #8
Attila Feher <at**********@lmf.ericsson.se> writes
See the post by tom_usenet in this thread.


Yep. This has been my first venture into comp.lang.c++ and I'm well
impressed at the quality and speed of the responses!
--
Simon Elliott
http://www.ctsn.co.uk/


Jul 19 '05 #9
WW
Simon Elliott wrote:
tom_usenet <to********@hotmail.com> writes
typedef void (__closure *MyCallback)(void);

Hmm, I think GCC has something like this too.


There was some talk about something along these lines being introduced
into the standard.


It was dapoted for the Library TR:

http://www.cuj.com/documents/s=8464/cujcexp0308sutter/

--
WW aka Attila
Jul 19 '05 #10
Simon Elliott wrote:

Karl Heinz Buchegger <kb******@gascad.at> writes
Simon Elliott wrote:

Is there a way I can do this without using the non standard __closure,
but still without "bar" needing a definition of "foo"? It would be nice
if "bar" could be contained by objects other than "foo" without needing
to change it each time.


Yep.
Define a class, eg. 'CallbackReceiver'
Every class wishing to use bar has to be derived
from that class. With multiple inheritance you
can add the 'feature' of being a callback receiver
very easily to each and every class.
bar::RunThebar expects a pointer to a CallbeckReceiver
object, which it uses to make the callback:


[snip]

Interesting idea, simpler and neater than my own inheritance based
solution.

Sadly it won't work in all the cases I'd like to use. I use Borland C++
Builder quite a lot, and any C++ object which inherits from an Object
Pascal/Delphi object can't use MI.


How about just doing

class Foo;
class Bar
{
public:
void doit(Foo *f);
};

class Foo
{
private:
Bar bar;
public:
Foo(Bar b) : bar(b) {}
void callback();
void doit() { bar.doit(this); }
};

void Bar::doit(Foo *foo) { foo->callback(); }

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
-- unknown
Jul 19 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: John Wood | last post by:
Let's say you're provided with an instance of a class. The instantiation takes place in another module that you have no control over. However, you've extended that class with your own value-added...
4
by: cmrchs | last post by:
Hi, how do I implement aggregation and how composition in C# ? When I say : an Airplane has a Pilot then I use aggregation but when I say : an Airplane has a Cockpit then I use composition. How...
2
by: Jozsef Bekes | last post by:
Hi, I would like to implement aggregation in C#, therefore I'd need to implement the queryinterface COM function of a class. I am not sure whether this can be done, and if yes where to start. If...
4
by: Frederik Vanderhaegen | last post by:
Hi, Can anyone explain me the difference between aggregation and composition? I know that they both are "whole-part" relationships and that composition parts are destroyed when the composition...
5
by: Nice Chap | last post by:
Aggregation in COM was defined as 'Exposing an interface of an inner object by the outer object as though it were an interface of the outer object'. Is this type of aggregation possible in vb.net(...
35
by: Michel Sanner | last post by:
Hello, One of the greatest feature of Python in my opinion is the way the interpreter can be used to integrate a wide variety of software packages by dynamically linking them. This approach has...
23
by: SenthilVel | last post by:
Hi Can any one let me know the websites/Pdf for learning Aggragation in C#?? Thanks Senthil
0
by: Karigar | last post by:
I have been so far developing COM servers and clients in C++. I am new to C#/NET way of doing COM and was wondering if it is possible to accomplish aggregation in .NET platform. By aggregation I...
1
by: OneShed | last post by:
Hi, I am trying to solve one problem. I have one object and I create another different object from it (aggregation). How can I now call methods of first object within the second object? Here is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.