function pointers and wrapper classes

M

mancomb

Hi,

I'm curious to the syntax of calling member functions through pointers
of classes returned through the -> operator. For example (excuse the
crude incomplete code);

Here are the classes:

Class Foo{

public:
doStuff();
};

Class FooRef{
Foo foo;
int refCount = 0;
public:
Foo& operator::->{refCount++;return foo;}
};

now here is my function

callStuff( FooRef& myFooRef, void (Foo::*doStuff)() )
{
myFooRef->doStuff(); // compiler error
myFooRef->*doStuff(); // compiler error
}

finally, here is the main:

main()
{
FooRef foor;
callStuff(foor, &Foo::doStuff);
}

I'm not sure what the correct syntax is to get this going inside the
callStuff function. Maybe I'm just forgetting something and doing this
is illegal.

thanks
 
M

Markus Grueneis

mancomb said:
Hi,

Hi!

I'm curious to the syntax of calling member functions through pointers
of classes returned through the -> operator.

Note: in the examples below you never returned any pointer to a class,
only references.
> For example (excuse the
crude incomplete code);

No comment.
Here are the classes:

Class Foo{

public:
doStuff();
};

Class FooRef{
Foo foo;
int refCount = 0;
public:
Foo& operator::->{refCount++;return foo;}
};

First: Syntax errors:
* consider copy and paste instead of writing code
in your newsgroup app
* class, not Class
* operator->(), not operator::->
* int refCount = 0; won't work. Initialize it in the c_tor.

Second:
* Do you really want/need a class FooRef? You probably want a
so-called smart pointer. I would suggest boost::shared_ptr, very easy,
very good. See boost.org. (Note that for boost specific questions there
exists a mailing list, also available via GMANE)
now here is my function

callStuff( FooRef& myFooRef, void (Foo::*doStuff)() )
{
myFooRef->doStuff(); // compiler error
myFooRef->*doStuff(); // compiler error
}

Well, actually the compiler error should happen when you write
'Class Foo', but that's not the point. And you must specify a return
type for callStuff. The parameter doStuff does not make any sense, as I
will explain below.
finally, here is the main:

main()
{
FooRef foor;
callStuff(foor, &Foo::doStuff);
}

What you meant is probably something like this:

int main()
{
FooRef foor;
foor->doStuff(); // that's it, nothing more.
return 0;
}

What you want is maybe this:

#include <boost/shared_ptr.hpp>
/// omitted class definition
typedef boost::shared_ptr<Foo> FooPtr;
int main()
{
FooPtr foor(new Foo());
foor->doStuff();
return 0;
}
I'm not sure what the correct syntax is to get this going inside the
callStuff function. Maybe I'm just forgetting something and doing this
is illegal.

The way you wrote it's more than just illegal, but I hope I guessed
right when I wrote what you actually want.


Best regards,
-- Markus
 
M

mancomb

Markus,

Thanks for your reply. The code in my original post was just pseudo
code intended to get some ideas of what I'm trying to do across. I
never expected that beast to compile anywhere but a parallel universe.
Yes the classes I'm dealing with are the shared pointers you mention.
Maybe I can use your clearer code to rephrase my question.

int main()
{
FooPtr foor(new Foo());
foor->doStuff();
return 0;
}

I want to pass my FooPtr into a function along with a pointer to the
function Foo::doStuff(). Then I would like to dereference my FooPtr
with the arrow operator and call the function doStuff through the
function pointer. If no FooPtr's were involved it would look like this:

// the function

void myFunc( Foo& myFoo, void Foo::*fooFunc() )
{
myFoo.*fooFunc();
}

// main:

int main()
{
Foo myFoo;
// assume Foo class has functions void doStuff(); and void
doMoreStuff();

myFunc(myFoo, &Foo::doStuff);
myFunc(myFoo, &Foo::doMoreStuff);
}

So I'd like myFunc to take in a FooPtr instead of just a Foo and still
keep it's functionality. Am I making sense yet or is it getting worse?

regards
 
M

mlimber

mancomb said:
Thanks for your reply. The code in my original post was just pseudo
code intended to get some ideas of what I'm trying to do across. I
never expected that beast to compile anywhere but a parallel universe.

That's nice, but see the FAQ on the polite way to post code that you
have a question about:

http://parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

In short, work up a minimal but complete (or as complete as possible)
example that we can paste unchanged into our editors to see the
problem.
Yes the classes I'm dealing with are the shared pointers you mention.
Maybe I can use your clearer code to rephrase my question.

int main()
{
FooPtr foor(new Foo());
foor->doStuff();
return 0;
}

I want to pass my FooPtr into a function along with a pointer to the
function Foo::doStuff(). Then I would like to dereference my FooPtr
with the arrow operator and call the function doStuff through the
function pointer. If no FooPtr's were involved it would look like this:

// the function

void myFunc( Foo& myFoo, void Foo::*fooFunc() )
{
myFoo.*fooFunc();
}

// main:

int main()
{
Foo myFoo;
// assume Foo class has functions void doStuff(); and void
doMoreStuff();

myFunc(myFoo, &Foo::doStuff);
myFunc(myFoo, &Foo::doMoreStuff);
}

So I'd like myFunc to take in a FooPtr instead of just a Foo and still
keep it's functionality. Am I making sense yet or is it getting worse?

The FAQ answers your questions, methinks:

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

Cheers! --M
 
M

Markus Grueneis

mancomb said:
Markus,

Thanks for your reply. The code in my original post was just pseudo
code intended to get some ideas of what I'm trying to do across. I
never expected that beast to compile anywhere but a parallel universe.

Please try to write minimal compiling samples for illustration. You'll
also get more answers faster and friendlier responses.
Yes the classes I'm dealing with are the shared pointers you mention.
Maybe I can use your clearer code to rephrase my question.

int main()
{
FooPtr foor(new Foo());
foor->doStuff();
return 0;
}

I want to pass my FooPtr into a function along with a pointer to the
function Foo::doStuff(). Then I would like to dereference my FooPtr
with the arrow operator and call the function doStuff through the
function pointer. If no FooPtr's were involved it would look like this:

// the function

void myFunc( Foo& myFoo, void Foo::*fooFunc() )
{
myFoo.*fooFunc();
}

// main:

int main()
{
Foo myFoo;
// assume Foo class has functions void doStuff(); and void
doMoreStuff();

myFunc(myFoo, &Foo::doStuff);
myFunc(myFoo, &Foo::doMoreStuff);
}

So I'd like myFunc to take in a FooPtr instead of just a Foo and still
keep it's functionality. Am I making sense yet or is it getting worse?

Both ;-) My codesample is already the solution to what you want to do,
really. You don't need a function 'myFunc'.

Assuming:
//------------------------------------------
class foo {
public:
void doStuff();
void doMoreStuff();
}

typedef boost::shared_ptr<foo> foo_ptr;
//------------------------------------------
Then you can call the methods doStuff() and doMoreStuff() via
derefencing a foo_ptr object:
//------------------------------------------
int main()
{
foo_ptr bar(new foo());
bar->doStuff(); // calls foo::doStuff with bar as this
bar->doMoreStuff();
return 0;
}
//------------------------------------------

You really do not need to write a call_stuff_through_foo_ptr() method;
to describe what happens behind the curtains:

Let's do:

foo* bar= new foo();

Now you could:

(*bar).doStuff();

Also written as:

bar->doStuff();

The operator-> is nothing special, here it is just syntactical sugar,
known from ancient C times. I am sure you know that you can call
methods this way. But what happens?

*bar

bar is of type 'pointer to foo', and variables of type 'pointer to ...'
can be dereferenced via the * operator; the result of applying the
dereference operator to a pointer is a ... (smile!) reference, in this
case, type 'reference to foo', also written as

foo&

Now, we are better, we use smart pointers. How they work is of no
interest to us in this stage. We just need to know that smart pointers
behave in almost all important cases like a raw pointer. This means
(with bar of type smart_ptr<foo>):

*bar

will be of type 'reference to foo'. Just like using a raw pointer. And

bar->doStuff()

will just call foo's member method doStuff(), applied on instance bar.


But maybe you meant applying non-member functions, which are only known
by signature and pointer, to an object. In this case, I recommend to
search the last week of this group for std::eek:stream and std::endl, where
an example of how to overload your operators to enable function
invocation is given.


best regards,
-- Markus
 
J

jois.de.vivre

mancomb said:
Markus,

Thanks for your reply. The code in my original post was just pseudo
code intended to get some ideas of what I'm trying to do across. I
never expected that beast to compile anywhere but a parallel universe.
Yes the classes I'm dealing with are the shared pointers you mention.
Maybe I can use your clearer code to rephrase my question.

int main()
{
FooPtr foor(new Foo());
foor->doStuff();
return 0;
}

I want to pass my FooPtr into a function along with a pointer to the
function Foo::doStuff(). Then I would like to dereference my FooPtr
with the arrow operator and call the function doStuff through the
function pointer. If no FooPtr's were involved it would look like this:

// the function

void myFunc( Foo& myFoo, void Foo::*fooFunc() )
{
myFoo.*fooFunc();
}

// main:

int main()
{
Foo myFoo;
// assume Foo class has functions void doStuff(); and void
doMoreStuff();

myFunc(myFoo, &Foo::doStuff);
myFunc(myFoo, &Foo::doMoreStuff);
}

Why this and not just

myFoo.doStuff()
myFoo.doMoreStuff()
 

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,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top