473,395 Members | 1,458 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.

Pointers to member functions.


I'm playing with a simulation where different parts of a system, like a
controller or a thermometer or a thermal mass, are represented as classes,
instantiated, and connected together like Tinkertoys. My thought at first
was that each class would have a member function like get_ouput(). When
some object like a thermal mass needs an input, like heat from a control
system, my thought was to add a pointer to that object to an internal
list, like

target.add_heat(&controller);

But I've discovered I want a little more flexibility to choose a member
function as the input. So I'd like to use something analogous to pointers
to regular functions, like

float (*pf)();
pf = controller.get_heat;
target.add_heat(pf);

But I've been playing with variations on that theme and I can't get it to
work.

Can I do this sort of thing in C++?

--
"Awareness means not just a vague, comfortable, fuzzy feeling. It means
explicit knowledge of current conditions." -- NBSR Radiation Safety
Training
Jul 23 '05 #1
11 1520
Gregory L. Hansen wrote:
I'm playing with a simulation where different parts of a system, like
a controller or a thermometer or a thermal mass, are represented as
classes, instantiated, and connected together like Tinkertoys. My
thought at first was that each class would have a member function
like get_ouput(). When some object like a thermal mass needs an
input, like heat from a control system, my thought was to add a
pointer to that object to an internal list, like

target.add_heat(&controller);

But I've discovered I want a little more flexibility to choose a
member function as the input. So I'd like to use something analogous
to pointers to regular functions, like

float (*pf)();
pf = controller.get_heat;
target.add_heat(pf);

But I've been playing with variations on that theme and I can't get
it to work.
What specifically can't you get to work?
Can I do this sort of thing in C++?


It's a good question, but why are you asking us? The question is
essentially about *your* ability, so, can *you* do it? If you wanted
to ask whether it's *possible* to do in C++, then the answer is "yes".
C++ is a general purpose language, and there is almost nothing that
cannot be done with it.

V
Jul 23 '05 #2
Gregory L. Hansen wrote:
I'm playing with a simulation where different parts of a system, like a
controller or a thermometer or a thermal mass, are represented as classes,
instantiated, and connected together like Tinkertoys. My thought at first
was that each class would have a member function like get_ouput(). When
some object like a thermal mass needs an input, like heat from a control
system, my thought was to add a pointer to that object to an internal
list, like

target.add_heat(&controller);

But I've discovered I want a little more flexibility to choose a member
function as the input. So I'd like to use something analogous to pointers
to regular functions, like

float (*pf)();
pf = controller.get_heat;
target.add_heat(pf);

But I've been playing with variations on that theme and I can't get it to
work.

Can I do this sort of thing in C++?


I don't think so, unless the functions are
non-member functions.

You might read the book "Design Patterns, Elements of
Reusable Object-Oriented Software" by Gamma, Helm,
Johnson, and Vlissides.

Perhaps an MVC (Model/View/Controller) approach, or the
"Mediator" design pattern would best meet your needs.

To quote from the "Design Patterns" Mediator section:

<quote>
Define an object that encapsulates how a set of objects interact.
Mediator promotes loose coupling by keeping objects from referring
to each other explicitly, and it lets you vary their interaction
independently.
..
..
..
Colleagues send and receive requests from a Mediator object.
The mediator implements the cooperative behavior by routing
requests between the appropriate colleague(s).
</quote>

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #3
Gregory L. Hansen wrote:
But I've discovered I want a little more flexibility to choose a member function as the input. So I'd like to use something analogous to pointers to regular functions, like

float (*pf)();
pf = controller.get_heat;
target.add_heat(pf);

But I've been playing with variations on that theme and I can't get it to work.
Can I do this sort of thing in C++?


Try these links:
http://www.parashift.com/c++-faq-lit...o-members.html
http://www.newty.de/fpt/index.html

::A::

Jul 23 '05 #4
"Gregory L. Hansen" wrote:

Try these links:
http://www.parashift.com/c++-faq-lit...o-members.html
http://www.newty.de/fpt/index.html
It confusing, I'm not sure I understand it.


The main point is:
The function pointer alone is not sufficient.
You want to call a member function of an object. For this
you need 2 informations: a pointer to the object itself and
a pointer to the member function of that object.
Looks like I need a static
wrapper for a non-static member.


That's the usual way it is done, when the interface of the class where
you register the callback is already fixed and cannot be changed.
But that is not your situation. You can change that interface to pass
those 2 informations: the pointer to the object and the pointer to a member
function of that object.

Study the following example. It shows how to call a a function foo and pass
an object and a member function of that object to it:

#include <iostream>
class Class
{
public:
double twice( double Nr ) { return 2 * Nr; }
double triple( double Nr ) { return 3 * Nr; }
};

typedef double (Class::*CallBackFnct)( double );

void foo( Class* pObject, CallBackFnct Function )
{
std::cout << (pObject->*(Function))( 5 ) << std::endl;
}

int main()
{
Class a;

foo( &a, Class::twice );
foo( &a, Class::triple );
}

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #5
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote:
>
>Try these links:
>http://www.parashift.com/c++-faq-lit...o-members.html
>http://www.newty.de/fpt/index.html
It confusing, I'm not sure I understand it.


The main point is:
The function pointer alone is not sufficient.
You want to call a member function of an object. For this
you need 2 informations: a pointer to the object itself and
a pointer to the member function of that object.
Looks like I need a static
wrapper for a non-static member.


That's the usual way it is done, when the interface of the class where
you register the callback is already fixed and cannot be changed.
But that is not your situation. You can change that interface to pass
those 2 informations: the pointer to the object and the pointer to a member
function of that object.

Study the following example. It shows how to call a a function foo and pass
an object and a member function of that object to it:


Looks like a clear example, but I need to spend some time with it to see
if I understand it. And, well, there seems to be little point in
discussing it before I do.

Thanks, I appreciate it.

#include <iostream>
class Class
{
public:
double twice( double Nr ) { return 2 * Nr; }
double triple( double Nr ) { return 3 * Nr; }
};

typedef double (Class::*CallBackFnct)( double );

void foo( Class* pObject, CallBackFnct Function )
{
std::cout << (pObject->*(Function))( 5 ) << std::endl;
}

int main()
{
Class a;

foo( &a, Class::twice );
foo( &a, Class::triple );
}

--
Karl Heinz Buchegger
kb******@gascad.at

--
"Pain is temporary, quitting lasts forever" -- Lance Armstrong
Jul 23 '05 #6
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote: Study the following example. It shows how to call a a function foo and pass
an object and a member function of that object to it:


Cool, it does work for me! I made my own function to pass things to. And
reducing it to the most basic level looks like

#include <iostream>

class Class
{
public:
double twice( double Nr ) { return 2 * Nr; }
double triple( double Nr ) { return 3 * Nr; }
};

int main()
{
Class a;
Class *c;
c = &a;
double (Class::* f)(double);
f = Class::twice;
cout << "Defined my own pointer, giving " << (a.*(f))(3) << endl;
f = Class::triple;
cout << "And then " << (c->*(f))(3) << endl;
}

And no static wrapper functions. That actually looks very much like
the sort of thing I wanted to do, except I didn't know the syntax.

Thanks!
--
"Usenet is like a herd of performing elephants with diarrhea -- massive,
difficult to redirect, awe-inspiring, entertaining, and a source of
mind-boggling amounts of excrement when you least expect it. "
-- Gene Spafford, 1992
Jul 23 '05 #7
In article <d5**********@rainier.uits.indiana.edu>,
Gregory L. Hansen <gl******@steel.ucs.indiana.edu> wrote:
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote:

Study the following example. It shows how to call a a function foo and pass
an object and a member function of that object to it:


Cool, it does work for me! I made my own function to pass things to. And
reducing it to the most basic level looks like


Except that my compiler keeps complaining about illegal implicit
typecasting, giving Warnings but not compilation-stopping Errors. What's
up with that?

--
"The polhode rolls without slipping on the herpolhode lying in the
invariable plane." -- Goldstein, Classical Mechanics 2nd. ed., p207.
Jul 23 '05 #8
"Gregory L. Hansen" wrote:

In article <d5**********@rainier.uits.indiana.edu>,
Gregory L. Hansen <gl******@steel.ucs.indiana.edu> wrote:
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote:

Study the following example. It shows how to call a a function foo and pass
an object and a member function of that object to it:


Cool, it does work for me! I made my own function to pass things to. And
reducing it to the most basic level looks like


Except that my compiler keeps complaining about illegal implicit
typecasting, giving Warnings but not compilation-stopping Errors. What's
up with that?


Rule number one:

if( you don't show us the actual code you have &&
don't tell us the exact error message &&
which line it refers to ) {
Nobody is able to help you
but the error is in line 42, as usual
}
else {
Someone can look at your code and try to figure out
what the problem could be
}

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #9
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote:

In article <d5**********@rainier.uits.indiana.edu>,
Gregory L. Hansen <gl******@steel.ucs.indiana.edu> wrote:
>In article <42***************@gascad.at>,
>Karl Heinz Buchegger <kb******@gascad.at> wrote:
>>"Gregory L. Hansen" wrote:
>
>>Study the following example. It shows how to call a a function foo and pass
>>an object and a member function of that object to it:
>
>Cool, it does work for me! I made my own function to pass things to. And
>reducing it to the most basic level looks like


Except that my compiler keeps complaining about illegal implicit
typecasting, giving Warnings but not compilation-stopping Errors. What's
up with that?


Rule number one:

if( you don't show us the actual code you have &&
don't tell us the exact error message &&
which line it refers to ) {
Nobody is able to help you
but the error is in line 42, as usual
}
else {
Someone can look at your code and try to figure out
what the problem could be
}


In the code you gave two messages ago, in main(). Specifically

int main()
{
Class a;

foo( &a, Class::twice );
foo( &a, Class::triple );
}

gcc won't compile it, and says--

karl.cpp: In function `int main()':
karl.cpp:22: assuming pointer to member `double Class::twice(double)'
karl.cpp:22: (a pointer to member can only be formed with `&
Class::twice(double)')
karl.cpp:23: assuming pointer to member `double Class::triple(double)'

CodeWarrior will compile and run it, but warns "illegal implicit member
pointer conversion" on those two lines.

--
"When the fool walks through the street, in his lack of understanding he
calls everything foolish." -- Ecclesiastes 10:3, New American Bible
Jul 23 '05 #10
"Gregory L. Hansen" wrote:

In the code you gave two messages ago, in main(). Specifically

int main()
{
Class a;

foo( &a, Class::twice );
foo( &a, Class::triple );
}

gcc won't compile it, and says--

karl.cpp: In function `int main()':
karl.cpp:22: assuming pointer to member `double Class::twice(double)'
Here it says: I assume that with "Class::twice" you mean a pointer
to the member function "double Class::twice(double)"
Please check, that indeed this is what you ment.
karl.cpp:22: (a pointer to member can only be formed with `&


And here it tells you what to do about it: use an '&' to explicitely
form the pointer:

foo( &a, &Class::twice );

What's complicated about that? The compiler even tells you what to do.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #11
In article <42***************@gascad.at>,
Karl Heinz Buchegger <kb******@gascad.at> wrote:
"Gregory L. Hansen" wrote:

In the code you gave two messages ago, in main(). Specifically

int main()
{
Class a;

foo( &a, Class::twice );
foo( &a, Class::triple );
}

gcc won't compile it, and says--

karl.cpp: In function `int main()':
karl.cpp:22: assuming pointer to member `double Class::twice(double)'


Here it says: I assume that with "Class::twice" you mean a pointer
to the member function "double Class::twice(double)"
Please check, that indeed this is what you ment.
karl.cpp:22: (a pointer to member can only be formed with `&


And here it tells you what to do about it: use an '&' to explicitely
form the pointer:

foo( &a, &Class::twice );

What's complicated about that? The compiler even tells you what to do.


Well, I tried that with

foo(&a, &(Class::twice));

and was told

karl.cpp: In function `int main()':
karl.cpp:22: Internal compiler error in resolve_offset_ref, at
cp/init.c:1886
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://bugzilla.redhat.com/bugzilla/> for instructions.

When I try it without the parentheses on my shell account I get a lot of
error messages related to std. There must be a library not installed or a
path not set or something. When I remove the output I get

//#include <iostream>
//using namespace std;

class Class
{
public:
double twice( double Nr ) { return 2 * Nr; }
double triple( double Nr ) { return 3 * Nr; }
};

typedef double (Class::*CallBackFnct)( double );

void foo( Class* pObject, CallBackFnct Function )
{
// cout << (pObject->*(Function))( 5 ) << endl;
double x = (pObject->*(Function))(5);
}

int main()
{
Class a;

foo( &a, &Class::twice );
foo( &a, &Class::triple );
}

gl******@krypton.iucf.indiana.edu: $ gcc karl.cpp
/tmp/cc8RybIb.o(.eh_frame+0x11): undefined reference to
`__gxx_personality_v0'
collect2: ld returned 1 exit status
gl******@krypton.iucf.indiana.edu: $
I don't understand the error message. At that point I figured something
was wrong, and didn't bother trying it with CodeWarrior. But I tried it
just now, with the ampersand and without the parentheses, and it ran just
fine.

--
"No one need be surprised that the subject of contagion was not clear to
our ancestors."-- Heironymus Fracastorius, 1546
Jul 23 '05 #12

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

Similar topics

5
by: xuatla | last post by:
Hi, I have the following code for function pointer. compiling is ok. Can you help me to check whether it's a good way to implement as: class CA { ..... private: void f1( double ) ;
4
by: Ian Malone | last post by:
I have a class which looks like this: class reco { public: int height, width; double beta; double mu; simple_d_field estimate; simple_d_field auxiliary;
7
by: jolie.demiranda | last post by:
Dear all, I'm fairly new to C++ so forgive me is this topic may have been convered before... I'm having a problem with pointers to member functions. Essentially what I want to achieve is the...
3
by: Bilgehan.Balban | last post by:
Hi, How do I declare an array of function pointers and assign each element of the array with public member functions of a class? Is it possible that the array is not a member of the class? ...
11
by: cps | last post by:
Hi, I'm a C programmer taking my first steps into the world of C++. I'm currently developing a C++ 3D graphics application using GLUT (OpenGL Utility Toolkit written in C) for the GUI...
12
by: addinall | last post by:
Hi guys and gals, Haven't been in here for a good decade or so! I'm having a braid-dead moment that is lasting for a couple of days. Declaring pointers to functions witrhin structures and...
5
by: Martijn van Buul | last post by:
Hi. I'm having a peculiar problem at work. I've been googling for it, but haven't found an authorative answer. In a nutshell (Long story follows), what I'd like to know is: If I have a C++...
22
by: sandy | last post by:
I am trying to make a simulated directory structure application for a course. I am using a Vector to store pointers to my Directory objects (as subdirectories of the current object). In my...
12
by: bgold | last post by:
Hey. I have a base class (SPRITE), and using this base class I have derived a large number of derived classes (PERSON, BULLET, MISSILE, etc.). Now, at a certain point in my program, I have a pair...
3
by: Ramesh | last post by:
Hi, I am trying to create an array of pointers to member functions inside my class. When I created a global array of type pfn & initialized with member functions and copy it back to the member...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.