Thread: Methods as arguments

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    5

    Methods as arguments

    Is it possible, like functions, to pass methods as arguments for other methods? If so, what is the syntax?

  2. #2

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    I wrote something like this:
    Code:
    #include <iostream>
    
    using namespace std;
    
    class Test{
        int x;
        typedef void (Test::*ptr) ( );
        public:
            void show ( )
            {
                cout << x << endl;
            } 
            Test ( int i ): x(i)
            {
            }
            void other_member(ptr p)
            {
               // p();//this is compiler error
            }
    };
    
    int main ( ) 
    {
        Test t(3);
        t.other_member( &Test::show );
      
        return 0;
    }
    But don't know how to call function on which pointer p points. If I remove comments I get compiler error wich means that I'm doing something very, very wrong. Must admit I never understood concept of pointers to member functions completely.
    Need to read that article!
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But don't know how to call function on which pointer p points.
    Could try:
    Code:
    void Test::other_member(ptr p)
    {
    	(this->*p)();
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    I never thought about that, thanks laserlight!
    I tried (*p)(); and p(); but it didn't occure to me to try with "this" pointer.
    I'm not sure I understand meaning of ->*. Can this part:
    Code:
    this->*p
    be interpreted as: for this object, find on which function points p and then execute it?
    please explain a little more real meaning of ->*?
    Last edited by Micko; 06-28-2006 at 04:38 AM.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    The arrow operator (->) is a language simplification of a common pointer usage. This usage is "dereference followed by the dot operator".

    Imagine a class called Car with a function member called Break. Imagine an object of this class called myCar. We normally access the function member with myCar.Break().

    But what to do if we then create a pointer to the myCar object?

    Car* myBrokenCar = &myCar;

    In order to access the Break member of myBrokenCar, it seems at first the sensible thing is to dereference the pointer and then access the function member:

    *myBrokenCar.Break();

    But that is an error. The problem is the dot operator has an higher precedence than the dereference operator. Has such, the compiler first tries to call the Break() function from myBrokenCar and only then to dereference the result. But since myBrokenCar is a pointer, it has no members. The above code gives a compiler error.

    The solution is then to force the dereference operator to act first by parenthesing it.

    (*myBrokenCar).Break();

    And that's it. Now it will work fine. But this usage is so common in C++ that the arrow operator was created to simplify the syntax.

    myBrokenCar->Break();


    Means dereference my left argument and apply the dot operator with my right argument. Just the same as the previous code.

    As such, I think it is easy for you to now see what it means to write ->*.

    If Break was itself a pointer to a function, it would mean to also derefer Break.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thank you Mario f. for explanation, but operator -> and it's meaning is known to me. However, I have trouble undertanding :
    why (this->*p)() works and why (this->(*p))() is an error?
    So, I need explanation regarding this particular problem, not general exaplanations about pointers and the way they're used.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ah. Didn't quite get your question before.

    Well, that happens with and without a pointer. And it happens for the same reason you can't do this...

    myCar.(Break())

    What is happening here?
    Break() is being evaluated even before you give the compiler a chance to make it a member of myCar.

    With pointers...

    (*myCar).(Break())
    The same happens.

    And with the arrow operator plus a function member pointer, the same thing happens...

    myCar->(*Break)

    And your particular example is even more insidious Being a function argument and all
    Last edited by Mario F.; 06-28-2006 at 06:44 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Ok, I understand now!
    Thanks
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    By the language definition, ".*" and "->*" are single operators, i.e. if you put parentheses before the *, it suddenly becomes two operators. And you cannot apply * to member pointers, only .* and ->*.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    FYI there are much cleaner ways of doing this using boost::bind, boost::function or even std::mem_fun.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  12. #12
    Registered User
    Join Date
    Jun 2006
    Posts
    5
    Thank you a lot guys!!!

  13. #13
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by ChaosEngine
    FYI there are much cleaner ways of doing this using boost::bind, boost::function or even std::mem_fun.

    Nice. Now... if only I could install boost on my system...
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You don't need to install it to use most of the boost libraries. Many are just simple headers that you can include in your program and use as is.

  15. #15
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Mario F.
    Nice. Now... if only I could install boost on my system...
    why can't you install boost? PM me if you have trouble with it, and I'll be happy to give you a hand.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. command line arguments
    By vurentjie in forum C Programming
    Replies: 3
    Last Post: 06-22-2008, 06:46 AM
  2. Property Methods, Constructors ??
    By guitar22891 in forum C# Programming
    Replies: 1
    Last Post: 10-28-2007, 10:27 AM
  3. Lesson #5 - Methods
    By oval in forum C# Programming
    Replies: 1
    Last Post: 05-04-2006, 03:09 PM
  4. NULL arguments in a shell program
    By gregulator in forum C Programming
    Replies: 4
    Last Post: 04-15-2004, 10:48 AM
  5. registry, services & command line arguments.. ?
    By BrianK in forum Windows Programming
    Replies: 3
    Last Post: 03-04-2003, 02:11 PM