Member function pointer woes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Albert

    Member function pointer woes

    Hi,

    I need to pass a pointer-to-member-function as a parameter to a function
    which takes pointer-to-function as an argument. Is there any way to do it
    besides overloading the function?

    Here is a small program I wrote to check if I could get the address of the
    function from the member-function-pointer, so that I could pass it to the
    function as a normal function-pointer.

    ---------------------------------------------------
    #include<stdio. h>

    class classname{
    public:
    int add(int a, int b){
    printf("inside add. \ta = %d, b = %d\n", a,b);
    return a+b;
    }
    }obj;


    typedef int(classname:: *mfptr)(int, int);
    typedef int (*fptr)(int, int);


    main(){

    mfptr mem_func_ptr;
    fptr func_ptr;

    mem_func_ptr = &classname::add ;
    func_ptr = (fptr)(&classna me::add);

    printf("&classn ame::add is %llx\n", &classname::add );
    printf("&classn ame::add is %llx\n", &classname::add );

    printf("mem_fun c_ptr is %llx\n", mem_func_ptr);
    printf("func_pt r is %x\n\n", func_ptr);

    printf("add called with func_ptr. sum is %d\n\n", func_ptr(2,3));
    printf("add called with mem_func_fptr. sum is %d\n\n",
    (obj.*mem_func_ ptr)(2,3));
    }

    -----------------------------------------------------


    I compiled it with the -Wno-pmf-conversions option. Here is the output of
    the program:

    ------------------------------------------
    &classname:: add is ffbeee78ff23e5d 0
    &classname:: add is ffbeee78ff243a4 c

    mem_func_ptr is ffbeee78ff243a4 c
    func_ptr is 109bc

    inside add. a = 3, b = 68028
    add called with func_ptr. sum is 68031

    inside add. a = 2, b = 3
    add called with mem_func_fptr. sum is 5

    ------------------------------------------


    A few questions:

    1. Why is the value of '&classname::ad d' in the two lines different?
    2. Why does the value of parameter 'b' change when 'classname::add ' is
    called with 'func_ptr'?
    3. If this approach is not correct, then could you please advise as to how
    to go about with it?

    Thanks.

    Albert.
  • John Harrison

    #2
    Re: Member function pointer woes


    "Albert" <albert@iitg.er net.in> wrote in message
    news:e9ced22e.0 406290508.5a913 be@posting.goog le.com...[color=blue]
    > Hi,
    >
    > I need to pass a pointer-to-member-function as a parameter to a function
    > which takes pointer-to-function as an argument. Is there any way to do it
    > besides overloading the function?[/color]

    No.

    [snip]
    [color=blue]
    > 3. If this approach is not correct, then could you please advise as to how
    > to go about with it?[/color]

    Write a normal function which calls your member function and then pass the
    normal function as a parameter.

    john


    Comment

    • Mark Warren

      #3
      Re: Member function pointer woes

      Albert wrote:[color=blue]
      > Hi,
      >
      > I need to pass a pointer-to-member-function as a parameter to a
      > function which takes pointer-to-function as an argument. Is there any
      > way to do it besides overloading the function?
      >
      > <snipped>
      >
      > 3. If this approach is not correct, then could you please advise as
      > to how to go about with it?[/color]

      I would advise you to consider using the Boost.Function library.


      I have used it to have a library function which can take pointer-to-function
      or pointer-to-member-function in different programs.

      Mark


      Comment

      • LNK2005

        #4
        Re: Member function pointer woes

        "Albert" <albert@iitg.er net.in> skrev i meddelandet
        news:e9ced22e.0 406290508.5a913 be@posting.goog le.com...[color=blue]
        > I need to pass a pointer-to-member-function as a parameter to a function
        > which takes pointer-to-function as an argument. Is there any way to do it
        > besides overloading the function?[/color]


        You could use a templated version of the subscriber/publisher pattern. The
        implementation isn't pretty, but the usage is kind of neat IMHO;-) Note that
        SubscriberBase and Subscriber can be reused for other notifications of the
        same type (for any class), in this case member functions that take an int
        and return void.

        // Base class for Subscriber. Must be a non-template since we
        // need to store a pointer to an instance.
        class SubscriberBase
        {
        public:
        virtual void exec(int) = 0;
        };

        // The actual Subscriber class template. Stores a pointer to an object and a
        pointer
        // to one of it's member functions.
        template<class T> class Subscriber : public SubscriberBase
        {
        private:
        typedef void (T::*EventFunc) (int);
        T *target; // Pointer to the object to recieve notification
        EventFunc func; // Pointer to member function to be called
        public:
        Subscriber(T *target, EventFunc func) : func(func), target(target) { }
        virtual void exec(int param) { (target->*func)(param ); }
        };

        // And this is how it's used.
        // Class that does stuff and notifies another object about something...
        class Publisher
        {
        protected:
        SubscriberBase *sub; // Could be a list really
        public:
        void registerSubscri ber(SubscriberB ase &s)
        {
        sub = &s;
        };
        void doSomething(int param)
        {
        // Do something
        // ...
        sub->exec(param); // ... and notify
        }
        };

        // Test class. Recieves notifications.
        class UserClass
        {
        public:
        // Starts the the entire thing
        void start()
        {
        // Publisher object that needs to tell this instance of UserClass about
        something
        Publisher test;

        // Construct and register a subscriber object.
        Subscriber<User Class> sub(this, callback);
        test.registerSu bscriber(sub);

        // Call a function that sends back notifications
        test.doSomethin g(12345);
        }

        // Callback member function
        void callback(int param)
        {
        cout << "Hello, " << param << endl;
        }
        };


        Comment

        • Bob Hairgrove

          #5
          Re: Member function pointer woes

          On 29 Jun 2004 06:08:33 -0700, albert@iitg.ern et.in (Albert) wrote:
          [color=blue]
          >Hi,
          >
          >I need to pass a pointer-to-member-function as a parameter to a function
          >which takes pointer-to-function as an argument. Is there any way to do it
          >besides overloading the function?
          >
          >Here is a small program I wrote to check if I could get the address of the
          >function from the member-function-pointer, so that I could pass it to the
          >function as a normal function-pointer.
          >
          >---------------------------------------------------
          >#include<stdio .h>[/color]

          Better to use <iostream> and cout, cin etc. instead of printf()...
          [color=blue]
          >class classname{
          > public:
          > int add(int a, int b){
          > printf("inside add. \ta = %d, b = %d\n", a,b);
          > return a+b;
          > }
          >}obj;[/color]
          ^^^
          What is that? Is this legal C++?
          [color=blue]
          >typedef int(classname:: *mfptr)(int, int);
          >typedef int (*fptr)(int, int);
          >
          >
          >main(){[/color]

          Always return int from main()...
          [color=blue]
          > mfptr mem_func_ptr;
          > fptr func_ptr;
          >
          > mem_func_ptr = &classname::add ;
          > func_ptr = (fptr)(&classna me::add);[/color]

          This cast will cause undefined behavior.

          [snip]
          [color=blue]
          >3. If this approach is not correct, then could you please advise as to how
          >to go about with it?[/color]

          As John said, create a normal (non-member) function which calls your
          member function. However, you need to remember that you must pass an
          object (or reference or pointer to an object) of your class in order
          to call the member function.

          --
          Bob Hairgrove
          NoSpamPlease@Ho me.com

          Comment

          • Rob Williscroft

            #6
            Re: Member function pointer woes

            Bob Hairgrove wrote in news:c913e0117r fj3fa6kob6pioiu b7qrbi3ak@4ax.c om in
            comp.lang.c++:
            [color=blue][color=green]
            >>class classname{
            >> public:
            >> int add(int a, int b){
            >> printf("inside add. \ta = %d, b = %d\n", a,b);
            >> return a+b;
            >> }
            >>}obj;[/color]
            > ^^^
            > What is that? Is this legal C++?
            >[/color]

            Yes its from C:

            struct X
            {
            int x;
            } x;

            Same as:

            struct X
            {
            int x;
            };

            struct X x; // in C and C++ and
            X x; // C++ only.

            This is why a semicolon is required after class/struct/union defenitions.

            Rob.
            --

            Comment

            • Mark Warren

              #7
              Re: Member function pointer woes

              Bob Hairgrove wrote:
              [color=blue]
              > On 29 Jun 2004 06:08:33 -0700, albert@iitg.ern et.in (Albert) wrote:
              >[color=green]
              >> class classname{
              >> public:
              >> int add(int a, int b){
              >> printf("inside add. \ta = %d, b = %d\n", a,b);
              >> return a+b;
              >> }
              >> }obj;[/color]
              > ^^^
              > What is that? Is this legal C++?[/color]

              It is perfectly legal.

              Mark


              Comment

              • Bob Hairgrove

                #8
                Re: Member function pointer woes

                On 29 Jun 2004 15:42:34 GMT, Rob Williscroft <rtw@freenet.co .uk>
                wrote:
                [color=blue]
                >Bob Hairgrove wrote in news:c913e0117r fj3fa6kob6pioiu b7qrbi3ak@4ax.c om in
                >comp.lang.c+ +:
                >[color=green][color=darkred]
                >>>class classname{
                >>> public:
                >>> int add(int a, int b){
                >>> printf("inside add. \ta = %d, b = %d\n", a,b);
                >>> return a+b;
                >>> }
                >>>}obj;[/color]
                >> ^^^
                >> What is that? Is this legal C++?
                >>[/color]
                >
                >Yes its from C:
                >
                >struct X
                >{
                > int x;
                >} x;[/color]

                No ... IF one uses this syntax in C++, it should be used like this:

                typedef struct X
                {
                int x;
                } x;

                and not for classes.
                [color=blue]
                >Same as:
                >
                >struct X
                >{
                > int x;
                >};
                >
                >struct X x; // in C and C++ and
                >X x; // C++ only.
                >
                >This is why a semicolon is required after class/struct/union defenitions.
                >
                >Rob.[/color]

                This syntax is not in the C++ standard ... although some compilers
                might accept it, it is not standard C++ as far as I can tell.

                Does that make it "legal"?
                --
                Bob Hairgrove
                NoSpamPlease@Ho me.com

                Comment

                • Xenos

                  #9
                  Re: Member function pointer woes


                  "Bob Hairgrove" <wouldnt_you_li ke@to_know.com> wrote in message
                  news:nfc3e0tl2j l8t9m5snil43q5p 9sbofkl8n@4ax.c om...[color=blue]
                  > On 29 Jun 2004 15:42:34 GMT, Rob Williscroft <rtw@freenet.co .uk>
                  > wrote:
                  >[color=green]
                  > >Bob Hairgrove wrote in news:c913e0117r fj3fa6kob6pioiu b7qrbi3ak@4ax.c om in
                  > >comp.lang.c+ +:
                  > >[color=darkred]
                  > >>>class classname{
                  > >>> public:
                  > >>> int add(int a, int b){
                  > >>> printf("inside add. \ta = %d, b = %d\n", a,b);
                  > >>> return a+b;
                  > >>> }
                  > >>>}obj;
                  > >> ^^^
                  > >> What is that? Is this legal C++?
                  > >>[/color]
                  > >
                  > >Yes its from C:
                  > >
                  > >struct X
                  > >{
                  > > int x;
                  > >} x;[/color]
                  >
                  > No ... IF one uses this syntax in C++, it should be used like this:
                  >
                  > typedef struct X
                  > {
                  > int x;
                  > } x;
                  >[/color]
                  No, he was declaring an object of the classes, not a typedef. The sytax is
                  legal.
                  [color=blue]
                  > and not for classes.[/color]
                  Yes it is.
                  [color=blue]
                  >[color=green]
                  > >Same as:
                  > >
                  > >struct X
                  > >{
                  > > int x;
                  > >};
                  > >
                  > >struct X x; // in C and C++ and
                  > >X x; // C++ only.
                  > >
                  > >This is why a semicolon is required after class/struct/union defenitions.
                  > >
                  > >Rob.[/color]
                  >
                  > This syntax is not in the C++ standard ... although some compilers
                  > might accept it, it is not standard C++ as far as I can tell.[/color]
                  Yes, it is standard and perfectly legal.
                  [color=blue]
                  >
                  > Does that make it "legal"?[/color]
                  moot point.


                  Comment

                  • Bob Hairgrove

                    #10
                    Re: Member function pointer woes

                    On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
                    <dont.spam.me@s pamhate.com> wrote:

                    [snip][color=blue]
                    >Yes, it is standard and perfectly legal.[/color]
                    [snip]

                    Well, I'm always willing to learn something new ... can you quote me
                    chapter and verse where this is written in the standard? I looked all
                    over, but did not find it.

                    (BTW, which is the "real" class name afterwards, X or obj)?

                    Thanks.

                    --
                    Bob Hairgrove
                    NoSpamPlease@Ho me.com

                    Comment

                    • Rob Williscroft

                      #11
                      Re: Member function pointer woes

                      Bob Hairgrove wrote in news:c1h3e0lnh9 vqh52r0sjh5r4hb 0492pu7h1@4ax.c om in
                      comp.lang.c++:
                      [color=blue]
                      > On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
                      > <dont.spam.me@s pamhate.com> wrote:
                      >
                      > [snip][color=green]
                      >>Yes, it is standard and perfectly legal.[/color]
                      > [snip]
                      >
                      > Well, I'm always willing to learn something new ... can you quote me
                      > chapter and verse where this is written in the standard? I looked all
                      > over, but did not find it.[/color]

                      Its quite hard to find, you need to chase down all the gramma
                      defenition's, search for "class-specifier" and "type-specifier".

                      Possibly you might want to start with the gramma summery in
                      appendix A (A.6 declaration's and A.8 classes).

                      In essence ( substitute ... with something leagal :) :

                      class X { ... } /* no semicolon */

                      is a class-specifier, which is also a type-specifier,
                      which is also a decl-specifier, which is the first part of
                      a simple-declaration.

                      The second part of a simple-declaration is the declarator,
                      i.e the thing being declared.

                      class X { ... } obj;

                      This declares the type 'X' and an instance of type 'X' 'obj'.

                      However 7/2 gives permission to omit the declarator in this
                      case (as X is also being declared), so in fact it is:

                      class X { ... };

                      Which is the exception to the rule.
                      [color=blue]
                      >
                      > (BTW, which is the "real" class name afterwards, X or obj)?
                      >[/color]

                      obj is not a type name its an instance of type classname (from
                      the OP's post).

                      Rob.
                      --

                      Comment

                      • Xenos

                        #12
                        Re: Member function pointer woes


                        "Bob Hairgrove" <wouldnt_you_li ke@to_know.com> wrote in message
                        news:c1h3e0lnh9 vqh52r0sjh5r4hb 0492pu7h1@4ax.c om...[color=blue]
                        > On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
                        > <dont.spam.me@s pamhate.com> wrote:
                        >
                        > [snip][color=green]
                        > >Yes, it is standard and perfectly legal.[/color]
                        > [snip]
                        >
                        > Well, I'm always willing to learn something new ... can you quote me
                        > chapter and verse where this is written in the standard? I looked all
                        > over, but did not find it.[/color]
                        For which part, the way he created the object or the different ways he used
                        the class name?

                        Do I really need to dig out the standard??? I *really* believe that these
                        are not syntatically correct???

                        struct X {
                        int x;
                        } obj;

                        struct X obj2;
                        X obj3;

                        Or did *I* misunderstand what he wrote?
                        [color=blue]
                        >
                        > (BTW, which is the "real" class name afterwards, X or obj)?[/color]
                        X is the class name. obj is an object of the class.



                        Comment

                        • Xenos

                          #13
                          Re: Member function pointer woes


                          "Xenos" <dont.spam.me@s pamhate.com> wrote in message
                          news:cbsi6r$edf 4@cui1.lmms.lmc o.com...[color=blue]
                          > Do I really need to dig out the standard??? I *really* believe that these
                          > are not syntatically correct???[/color]

                          Sorry. Replace "I" in the second sentence to "Do you."



                          Comment

                          • Bob Hairgrove

                            #14
                            Re: Member function pointer woes

                            On 29 Jun 2004 20:19:39 GMT, Rob Williscroft <rtw@freenet.co .uk>
                            wrote:

                            [snip lots of patient explanation][color=blue]
                            >class X { ... } obj;
                            >
                            >This declares the type 'X' and an instance of type 'X' 'obj'.
                            >
                            >However 7/2 gives permission to omit the declarator in this
                            >case (as X is also being declared), so in fact it is:
                            >
                            >class X { ... };
                            >
                            >Which is the exception to the rule.
                            >[color=green]
                            >>
                            >> (BTW, which is the "real" class name afterwards, X or obj)?
                            >>[/color]
                            >
                            >obj is not a type name its an instance of type classname (from
                            >the OP's post).[/color]

                            Thanks very much for your patience ... I totally screwed up here,
                            missing "obj" for the instance name!

                            That's what happens after you have been indoctrinated for 10+ years to
                            always separate the class declaration from the implementation.

                            --
                            Bob Hairgrove
                            NoSpamPlease@Ho me.com

                            Comment

                            • Bob Hairgrove

                              #15
                              Re: Member function pointer woes

                              On Tue, 29 Jun 2004 16:07:48 -0400, "Xenos"
                              <dont.spam.me@s pamhate.com> wrote:
                              [color=blue]
                              >
                              >"Bob Hairgrove" <wouldnt_you_li ke@to_know.com> wrote in message
                              >news:c1h3e0lnh 9vqh52r0sjh5r4h b0492pu7h1@4ax. com...[color=green]
                              >> On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
                              >> <dont.spam.me@s pamhate.com> wrote:
                              >>
                              >> [snip][color=darkred]
                              >> >Yes, it is standard and perfectly legal.[/color]
                              >> [snip]
                              >>
                              >> Well, I'm always willing to learn something new ... can you quote me
                              >> chapter and verse where this is written in the standard? I looked all
                              >> over, but did not find it.[/color]
                              >For which part, the way he created the object or the different ways he used
                              >the class name?[/color]
                              [snip]

                              I totally missed the fact that he was *creating an instance* of his
                              class immediately after the class declaration (see my post to Rob W.
                              for more...).

                              Sorry for the FUD.

                              --
                              Bob Hairgrove
                              NoSpamPlease@Ho me.com

                              Comment

                              Working...