pointers to member functions

J

jolie.demiranda

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 following:

class A {
public:
double (A::*ptrToFunction)(double);
}

// and NOTHING else is in class A.

class B : public A {
public:
double function1(double);
double function2(double);
double function3(double);
}

// and NOTHING else is in class B.

Later on, I would like to do the following:

class ApplyCoolFunctions {
public:
double apply(A &a);
}

where

ApplyCoolFunctions::apply(A *a) {
a->*ptrToFunction(20.0);
}

The idea being that I can feed in objects of class B to
ApplyCoolFUnctions, i.e. with calls like:

B b;
b.ptrToFunction = &B::function1;
ApplyCoolFunctions(&b);
b.ptrToFunction = &B::funcion2;
ApplyCoolFunction(&b);

But... it doesn't work!! Is what I'm doing even possible? Or does the
fact that function1, function2, etc... are NOT defined in A mean that
what I am trying to do is impossible.

Any help with be greatly appreciated.

Thanks,
Jolie
 
J

John McCabe

B b;
b.ptrToFunction = &B::function1;
ApplyCoolFunctions(&b);
b.ptrToFunction = &B::funcion2;
ApplyCoolFunction(&b);

But... it doesn't work!! Is what I'm doing even possible? Or does the
fact that function1, function2, etc... are NOT defined in A mean that
what I am trying to do is impossible.

At first glance it looks like you would need to declare
function1/function2/function3 as static for this to work. You have
them defined as class member functions which cannot be assigned in
this way.

This should hopefully give you a starting point to help you on your
way to finding out what you should be doing.
 
J

John Harrison

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 following:

class A {
public:
double (A::*ptrToFunction)(double);
}

// and NOTHING else is in class A.

class B : public A {
public:
double function1(double);
double function2(double);
double function3(double);
}

// and NOTHING else is in class B.

Later on, I would like to do the following:

class ApplyCoolFunctions {
public:
double apply(A &a);
}

where

ApplyCoolFunctions::apply(A *a) {
a->*ptrToFunction(20.0);
}

The idea being that I can feed in objects of class B to
ApplyCoolFUnctions, i.e. with calls like:

B b;
b.ptrToFunction = &B::function1;
ApplyCoolFunctions(&b);
b.ptrToFunction = &B::funcion2;
ApplyCoolFunction(&b);

But... it doesn't work!! Is what I'm doing even possible? Or does the
fact that function1, function2, etc... are NOT defined in A mean that
what I am trying to do is impossible.

Any help with be greatly appreciated.

Thanks,
Jolie

Two errors

1) Syntax should be

(a->*(a->ptrToFunction))(20.0);

2) Concept doesn't work. Consider B::function1, that is a member
function which must be called with a B object or an object derived from
B. If you could assign it to a pointer to member function of A, then it
would possible to call a B member function with an A object. So the
assignment is not allowed.

john
 
V

Victor Bazarov

I'm fairly new to C++ so forgive me is this topic may have been
convered before...

It's also probably covered in the FAQ Lite. Have you read it?
> I'm having a problem with pointers to member
functions. Essentially what I want to achieve is the following:

class A {
public:
double (A::*ptrToFunction)(double);
}
;
// and NOTHING else is in class A.

class B : public A {
public:
double function1(double);
double function2(double);
double function3(double);
}
;
// and NOTHING else is in class B.

Later on, I would like to do the following:

class ApplyCoolFunctions {
public:
double apply(A &a);
}
;
where

ApplyCoolFunctions::apply(A *a) {

That's

double ApplyCoolFunctions::apply(A &a) {

(why'd you switch the argument type and lost the return value type?)
a->*ptrToFunction(20.0);

That's not how you call it. Should be

(a.*ptrToFunction)(20.0);

('a' is actually a reference and the syntax requires the parentheses).
}

The idea being that I can feed in objects of class B to
ApplyCoolFUnctions, i.e. with calls like:

B b;
b.ptrToFunction = &B::function1;

That's not going to fly. You are trying to assign a member of B to
a pointer to a member of A. The language only defines the _reverse_
as an implicit conversion. Any member of A is a member of B, but not
vice versa.
ApplyCoolFunctions(&b);
b.ptrToFunction = &B::funcion2;
ApplyCoolFunction(&b);

But... it doesn't work!!

Read the FAQ 5.8.
> Is what I'm doing even possible?

Depending on what you're trying to accomplish. Are you attempting some
kind of polymorphic behaviour without using virtual functions? It seems
so, but I cannot be sure. Why not use virtual functions?
> Or does the
fact that function1, function2, etc... are NOT defined in A mean that
what I am trying to do is impossible.

You could try using static_cast:

b.ptrToFunction = static_cast<double(A::*)(double)>(&B::function2);

.... But I am still not convinced that it's the best approach.

V
 
A

Alf P. Steinbach

* (e-mail address removed):
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 following:

class A {
public:
double (A::*ptrToFunction)(double);
}

// and NOTHING else is in class A.

class B : public A {
public:
double function1(double);
double function2(double);
double function3(double);
}

// and NOTHING else is in class B.

Later on, I would like to do the following:

class ApplyCoolFunctions {
public:
double apply(A &a);
}

where

ApplyCoolFunctions::apply(A *a) {
a->*ptrToFunction(20.0);
}

A class is not a function. Don't think of a class as "doing" something.
A class can model a function, but you don't need that.

The idea being that I can feed in objects of class B to
ApplyCoolFUnctions, i.e. with calls like:

B b;
b.ptrToFunction = &B::function1;
ApplyCoolFunctions(&b);
b.ptrToFunction = &B::funcion2;
ApplyCoolFunction(&b);

But... it doesn't work!! Is what I'm doing even possible? Or does the
fact that function1, function2, etc... are NOT defined in A mean that
what I am trying to do is impossible.

Any help with be greatly appreciated.

You need ordinary function pointers or virtual member functions, not
pointers to member functions.

It's hard to figure out what you're trying to do since most of the above
is concerned with an attempt at a technical solution to ... something.

What exactly is it you want applyCoolFunctions() to do?
 
J

John Harrison

2) Concept doesn't work. Consider B::function1, that is a member
function which must be called with a B object or an object derived from
B. If you could assign it to a pointer to member function of A, then it
would possible to call a B member function with an A object. So the
assignment is not allowed.

You would be OK if A derived from B, but not the other way around.

john
 
J

jolie.demiranda

Essentially what I am trying to do is copy the idea of a "foldr"
function or something like a "map" function, which takes a function as
a parameter and then applies to recursively/iteratively to to some data
structure.

SO, for example, if I defined the function

double add2(double d) {
return d+2.0;
}

and then I would like to do the following: map(add2) listofDoubles;
where listOfDoubles is an array of doubles.

Anyway, I'm not really after a map, but the same principle applies. I
want to take a function as a parameter and I want want to work through
a kind of tree applying the function supplied to each node in the tree.

Now, the idea is that there are several classes I want to implement,
each of which can list a number of functions.

For example, class A might have 12 functions it needs to apply, class B
has 2, class C might have 4 and so forth. So, what I was hoping is that
A, B, C could all have base class X, where X basically just contained a
function pointer, and then, inside A, for example, I could get the
function pointer (inherited from X) to point to a different function
defined in A whenever I wanted to.

The idea is then that there is some other class which contains a
function
applyCoolFunction(X *x) {
}
and then it would take an X object and based on what X's pointer
function is pointing to apply that function...?

So inside class A, i would at some point
make the functionpointer point to function1, then call
applyCoolFunction(this);
then later on I would make the functionpointer point to function2, then
call
applyCoolFunction(this);
and so forth.

BY the way, none of the functions defined in class A , B or C are meant
to be static.

THanks,
Jolie
 
A

Alf P. Steinbach

* (e-mail address removed):
Essentially what I am trying to do is copy the idea of a "foldr"
function or something like a "map" function, which takes a function as
a parameter and then applies to recursively/iteratively to to some data
structure.

SO, for example, if I defined the function

double add2(double d) {
return d+2.0;
}

and then I would like to do the following: map(add2) listofDoubles;
where listOfDoubles is an array of doubles.

#include <algorithm> // std::copy, std::transform
#include <iterator> // std::eek:stream_iterator
#include <iostream> // std:.cout
#include <ostream> // <<, std::endl
#include <vector> // std::vector

void display( std::vector<int> const& v )
{
std::copy(
v.begin(), v.end(),
std::eek:stream_iterator<int>( std::cout, " " )
);
std::cout << std::endl;
}

int add2( int x ) { return x+2; }

int main()
{
static int const data[] = {1, 2, 3};
std::vector<int> v( data, data + 3 );

display( v );
std::transform( v.begin(), v.end(), v.begin(), add2 );
// std::transform is the C++ "apply".
display( v );
}


You know, this is rather interesting. For when I replace 'int' with
'double' my trusty old Microsoft Visual C++ 7.1 compiler says:

fatal error C1001: INTERNAL COMPILER ERROR (compiler file
'f:\vs70builds\3077\vc\Compiler\Utc\src\P2\main.c', line 148)

And guess what, it's the old 'int main' issue raring its ugly head.

For my editor of course changed that to 'double main' -- so now I know
the two thousand and forty third way of ICEing this compiler...

Anyway, I'm not really after a map,

Any function is a map, isn't it?

but the same principle applies. I
want to take a function as a parameter and I want want to work through
a kind of tree applying the function supplied to each node in the tree.

You can use a function pointer or an object with a virtual member
function or a functor object, but don't use member function pointers.

E.g.,

typedef double FuncFoo( double x );

void apply( Node& node, FuncFoo foo )
{
node.data = foo( node.data );
apply( *node.left, foo );
apply( *node.right, foo );
}

Now, the idea is that there are several classes I want to implement,
each of which can list a number of functions.

For example, class A might have 12 functions it needs to apply, class B
has 2, class C might have 4 and so forth. So, what I was hoping is that
A, B, C could all have base class X, where X basically just contained a
function pointer, and then, inside A, for example, I could get the
function pointer (inherited from X) to point to a different function
defined in A whenever I wanted to.

?

I think you'd better forget that idea for a solution. Don't think in
terms of changing function pointers. Just supply the relevant functions
or objects or whatever as arguments to your 'apply' function.
 

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

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top