Z’s

July 16, 2008

Pointer To C++ Class Methods; Or Should You Call ‘em “Method Pointers”?

This one is after a real long break from blogs :) .
Function pointer is pretty commonplace among C/C++ developers unlike “pointer to C++ class methods.” For those who have never used it or even heard of it; it really is very similar to “Function Pointer” from outside, though its internal mechanism is entirely different and its syntax is quite ugly. So, without much literature, let’s see how one would make a pointer to a C++ method. Before that, let’s review the usual function pointer of C a little bit:

// define a function type FUNCTION that takes int and char* as argument

typedef int (*FUNCTION) (int, char*);

// Declare a funciton pointer f of type FUNCTION

// and make f point to some function that takes int and char* as argument.

FUNCTION f = some_function;

// Simply call the function with an int and char* argument

f(10,“Hello”);

So that’s how function pointers are dealt in C. Following is a snippet that shows how to declare a function pointer that points to a method of a C++ class and then finally shows how to call that method via the function pointer (or “method pointer,” if you like to call it that way):

// A sample class, lets call it Base

// with a sample method called “Method”

class Base{

public:

int Method( int i, char *str )

{

printf(“Inside Base::Method: %d, %s\n”,i,str);

return 0;

}

};

// Note how FNMETHOD is defined. This is very similar to C function pointer

// definition just that the type is preceded by the class name and “::”.

// The class name is important and this tells that FNMETHOD can only point to

// the methods of type (int, char*) and only of class Base and it’s derivatives.

typedef int (Base::*FNMETHOD) ( int, char* );

// Later somewhere else in the code….

// Declare a function pointer f of type FNMETHOD and make it

// point to a method of the Base class, e.g. Base::Method.

// Note the usage of & symbol and this is important. For C,& is not

// necessary for the assignment but for C++ method it is necessary.

FNMETHOD f = &Base::Method;

// Now create an object of Base

Base *pBase = new Base();

// This is how f can be called with an instance of Base. Note the syntax, with

// care give to the * operator and brackets. You must need an intance of Base

// to call f because you need to pass the “this” pointer to the methods right?

(pBase->*f)(10,“Hello”);

Can you see the resemblance between C++ “method pointers” the usual C function pointers? Obviously, I can write a whole big chapter on this “Method Pointers” and how they all work under the hood (which is quite different from function pointers of C) but I will stop it here as writing in on every detail might bore you to death. If you want to learn more, just google a little bit; you will find thousands of articles on this topic which go into extreme details. For the moment; all I can add is: this “method pointers” works perfectly for even virtual functions and derived classes. But, there is a little catch, see the following:

class Base{

public:

virtual int Method( int i, char *str )

{

printf(“Inside Base::Method: %d, %s\n”,i,str);

return 0;

}

};

// A derived class of Base with overrides Method

class Derived : public Base{

public:

virtual int Method( int i, char *str )

{

printf(“Inside Derived::Method: %d, %s\n”,i,str);

return 0;

}

};

// Note the type FNMETHOD is defined on Base class

typedef int (Base::*FNMETHOD) ( int, char* );

// HERE IS THE CATCH; Notice that f is pointing to the method of the

// Base class but eventually runtime will decide, based on the object pointer,

// which method will be called, Base::Method or Derived::Method.The

// bad thing is if Derived class overrides Base::Method then, as a matter

// of fact,FNMETHOD f = &Derived::Method will give compiler error!

FNMETHOD f = &Base::Method;

// Now create an object of Derived!

Base *pBase = new Derived();

// Verify that the Method of Derived is called!

(pBase->*f)(10,“Hello”);

If you want to know more about the above “catch” situation, then I would suggest you try out the above example yourself and experiment a lot!
Finally, you must be wondering, why would you ever need pointer to a C++ method. Honestly, you can, most of the time, avoid using it unless you are trying to implement something like MFC message mapping or something similar to the Delegates of C#. However, truest form of C# Delegate is not probably implementable using this “C++ method pointer” (correct me if I am wrong). Message mapping for GUI or other similar codes are like the perfect places for using “method pointers” where you want a particular method of a particular instance of a class to be called upon some event (like call-backs).
Just as a little homework: try to figure out and google about how C++ method pointer works under the hood and how also achieves polymorphism (as shown above).

About these ads

4 Comments »

  1. Thank you, really, thank you very much.

    This is what I can call a good tutorial.

    Comment by Victor Calderon — August 8, 2008 @ 8:08 pm | Reply

  2. hi
    and thank you for this article.
    i create Base Calss Called Object in (DOS C++ 3.0)
    in header file i defined : typedef void (Object::*EventHandler)();
    i Create Timer Class that have Tick Event(Inherited Object).
    also i Create Cursor Class(Inherited Object), in this class i create new Timer Object
    and i want te set one of TimerObject->Tick = Cursor::Timer_Tick;
    but i cant do this, how can i solve this?

    Comment by Univ2Univ.ir — December 2, 2008 @ 6:13 am | Reply

  3. Hi,

    I’ve another query related to member function and member data variables.
    Consider below example

    Class Hype{
    private:
    int data;
    public:
    int get(){return data;}
    void set(int d){data=d;}
    };
    int main()
    {
    Hype h1,h2,h3;
    int a,b,c;
    h1.set(10);
    h2.set(20);
    h3.set(30);
    a= h1.get();
    b= h2.get();
    c= h3.get();
    return 1;
    }
    w.r.t. above example I wanted to ask a weird question.
    we are calling functions of class with objects of the class.
    But how would the function know where actually the h1.data, h2,data or h3.data is stored in memory?
    because internally we are operating upon data-member of that specific object which will have different memory locations for each of them?
    So when we call h1.set(10) or h1.get() does the function gets any extra information about the objects location in memory? how?
    Can someone pls answer this question?

    Thanks
    Himanshu

    Comment by Himanshu — June 4, 2009 @ 2:38 pm | Reply

  4. Pls let me know if someone can help me get the answer!

    Comment by Himanshu — June 4, 2009 @ 2:40 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: