function pointers and wrapper classes

Discussion in 'C++' started by mancomb, Sep 20, 2006.

  1. mancomb

    mancomb Guest

    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
    mancomb, Sep 20, 2006
    #1
    1. Advertising

  2. mancomb schrieb:
    > 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

    > thanks
    >
    Markus Grueneis, Sep 20, 2006
    #2
    1. Advertising

  3. mancomb

    mancomb Guest

    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
    mancomb, Sep 20, 2006
    #3
  4. mancomb

    mlimber Guest

    mancomb wrote:
    > 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
    mlimber, Sep 20, 2006
    #4
  5. mancomb schrieb:
    > 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

    > regards
    >
    Markus Grueneis, Sep 20, 2006
    #5
  6. mancomb

    Guest

    mancomb wrote:
    > 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()

    >
    > 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
    , Sep 20, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Phil
    Replies:
    1
    Views:
    644
    llewelly
    Sep 16, 2003
  2. Replies:
    11
    Views:
    1,300
    Chris Uppal
    Dec 4, 2006
  3. n2xssvv g02gfr12930

    Smart pointers and member function pointers

    n2xssvv g02gfr12930, Nov 26, 2005, in forum: C++
    Replies:
    3
    Views:
    468
    n2xssvv g02gfr12930
    Nov 27, 2005
  4. Replies:
    6
    Views:
    367
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    672
Loading...

Share This Page