Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Function Pointers in Classes

Function Pointers in Classes

Scheduled Pinned Locked Moved C / C++ / MFC
csharpc++visual-studiohelpquestion
14 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Arsalan Malik

    I have two independent C++ classes, A and B. I have a non-static public function in class A

    void display(char *msg);

    I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:

    void (*display)(char*);

    I have a member of class B in class A, and I am trying to set function pointer as:

    B b;
    b.display = &A::display;

    I get the following compiler error:

    error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'

    I am using Visual Studio 2005. Can any one let me know a proper way of doing this?

    ARSALAN MALIK

    S Offline
    S Offline
    Stephen Hewitt
    wrote on last edited by
    #2

    Firstly, your approach using void (*display)(char*); doesn't work as it points to a global or static class member function, not a member function. One way to to do it is the following, assuming the function to be called is always display:

    1. Define an interface that contains the function:

      class ICallable
      {
      public:
      virtual void display(char *msg) = 0;
      };

      Note the function is a pure virtual function.

    2. Derive the classes that have the function to be called from it:

      class A : public ICallable
      {
      public:
      virtual void display(char *msg)
      {
      // A's impelentation here...
      }
      };

    3. Your pointer now looks like the following:

      ICallable *pPointer;

    4. The call through the pointer like this:

      pPointer->display("Hello world!");

    Steve

    A 1 Reply Last reply
    0
    • A Arsalan Malik

      I have two independent C++ classes, A and B. I have a non-static public function in class A

      void display(char *msg);

      I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:

      void (*display)(char*);

      I have a member of class B in class A, and I am trying to set function pointer as:

      B b;
      b.display = &A::display;

      I get the following compiler error:

      error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'

      I am using Visual Studio 2005. Can any one let me know a proper way of doing this?

      ARSALAN MALIK

      P Offline
      P Offline
      ParagPatel
      wrote on last edited by
      #3

      What is your requirement? Is it ok if you have static "display" function in class A?

      Parag Patel Sr. Software Eng, Varaha Systems

      1 Reply Last reply
      0
      • A Arsalan Malik

        I have two independent C++ classes, A and B. I have a non-static public function in class A

        void display(char *msg);

        I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:

        void (*display)(char*);

        I have a member of class B in class A, and I am trying to set function pointer as:

        B b;
        b.display = &A::display;

        I get the following compiler error:

        error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'

        I am using Visual Studio 2005. Can any one let me know a proper way of doing this?

        ARSALAN MALIK

        D Offline
        D Offline
        Divyang Mithaiwala
        wrote on last edited by
        #4

        What you have done is shown that you want some common operation in display method of class A & class B. So, for that here you can take one base class which define display method. And after that you can inherit your 2 classes A & B from that base class. Both have access of display method.


        Do not trust a computer... Always check what computer is doing regards, Divyang Mithaiwala Software Engineer

        1 Reply Last reply
        0
        • A Arsalan Malik

          I have two independent C++ classes, A and B. I have a non-static public function in class A

          void display(char *msg);

          I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:

          void (*display)(char*);

          I have a member of class B in class A, and I am trying to set function pointer as:

          B b;
          b.display = &A::display;

          I get the following compiler error:

          error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'

          I am using Visual Studio 2005. Can any one let me know a proper way of doing this?

          ARSALAN MALIK

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #5

          I would implement this using Boost.Function[^] and Boost.Bind[^]: In class B, declare display like this:

          boost::function<void(char*)> display;

          in A, set b.display like this:

          B b;
          b.display = boost::bind(&A::display, this);

          in B, call it like this:

          if (display) display(whatever string you want to display

          The if (display) bit is to protect you against the case that nothing's been assigned to B::display. Here's a complete, buildable and runnable example:

          #include <iostream>
          #include <boost/bind.hpp>
          #include <boost/function.hpp>

          class B
          {
          public:
          boost::function<void(char*)> display;
          void b_test() { if (display) display("test"); }
          };

          class A
          {
          public:
          A() { b.display = boost::bind(&A::display, this, _1); }
          void a_test() { b.b_test(); }
          void display(char* s) { std::cout << s << std::endl; }
          B b;
          };

          int main()
          {
          A a;
          a.a_test();
          }

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          L 1 Reply Last reply
          0
          • S Stuart Dootson

            I would implement this using Boost.Function[^] and Boost.Bind[^]: In class B, declare display like this:

            boost::function<void(char*)> display;

            in A, set b.display like this:

            B b;
            b.display = boost::bind(&A::display, this);

            in B, call it like this:

            if (display) display(whatever string you want to display

            The if (display) bit is to protect you against the case that nothing's been assigned to B::display. Here's a complete, buildable and runnable example:

            #include <iostream>
            #include <boost/bind.hpp>
            #include <boost/function.hpp>

            class B
            {
            public:
            boost::function<void(char*)> display;
            void b_test() { if (display) display("test"); }
            };

            class A
            {
            public:
            A() { b.display = boost::bind(&A::display, this, _1); }
            void a_test() { b.b_test(); }
            void display(char* s) { std::cout << s << std::endl; }
            B b;
            };

            int main()
            {
            A a;
            a.a_test();
            }

            Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

            L Offline
            L Offline
            led mike
            wrote on last edited by
            #6

            Stuart Dootson wrote:

            I would implement this using Boost.Function[^] and Boost.Bind[^]:

            The Visual C++ 2008 Feature Pack has implemented TR1[^] Although, I would prefer using interfaces as Stephen Hewitt posted.

            S 1 Reply Last reply
            0
            • A Arsalan Malik

              I have two independent C++ classes, A and B. I have a non-static public function in class A

              void display(char *msg);

              I want to have its function pointer as a public member of class B, without information that it belongs to class A, e.g in class B, I have:

              void (*display)(char*);

              I have a member of class B in class A, and I am trying to set function pointer as:

              B b;
              b.display = &A::display;

              I get the following compiler error:

              error: '=' : cannot convert from 'void (__thiscall A::* )(char *)' to 'void (__cdecl *)(char *)'

              I am using Visual Studio 2005. Can any one let me know a proper way of doing this?

              ARSALAN MALIK

              C Offline
              C Offline
              CPallini
              wrote on last edited by
              #7

              Why do you want to follow a very plain-C path? You know, C++ is a fully featured OOP launguage. :)

              If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
              This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
              [My articles]

              A 1 Reply Last reply
              0
              • L led mike

                Stuart Dootson wrote:

                I would implement this using Boost.Function[^] and Boost.Bind[^]:

                The Visual C++ 2008 Feature Pack has implemented TR1[^] Although, I would prefer using interfaces as Stephen Hewitt posted.

                S Offline
                S Offline
                Stuart Dootson
                wrote on last edited by
                #8

                led mike wrote:

                The Visual C++ 2008 Feature Pack has implemented TR1[^]

                Caught me - I've not got used to having TR1 yet. Also, TR1 doesn't have Boost.Bind in it :-( (or Boost.Lambda, for that matter - even more :-()

                led mike wrote:

                Although, I would prefer using interfaces as Stephen Hewitt posted.

                Fair enough - each approach has its own benefits and drawbacks.

                Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                L 1 Reply Last reply
                0
                • S Stuart Dootson

                  led mike wrote:

                  The Visual C++ 2008 Feature Pack has implemented TR1[^]

                  Caught me - I've not got used to having TR1 yet. Also, TR1 doesn't have Boost.Bind in it :-( (or Boost.Lambda, for that matter - even more :-()

                  led mike wrote:

                  Although, I would prefer using interfaces as Stephen Hewitt posted.

                  Fair enough - each approach has its own benefits and drawbacks.

                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                  L Offline
                  L Offline
                  led mike
                  wrote on last edited by
                  #9

                  Stuart Dootson wrote:

                  Also, TR1 doesn't have Boost.Bind in it Frown (or Boost.Lambda, for that matter - even more Frown)

                  Well no, there is no Boost namespace but those features are in TR1.

                  S 1 Reply Last reply
                  0
                  • L led mike

                    Stuart Dootson wrote:

                    Also, TR1 doesn't have Boost.Bind in it Frown (or Boost.Lambda, for that matter - even more Frown)

                    Well no, there is no Boost namespace but those features are in TR1.

                    S Offline
                    S Offline
                    Stuart Dootson
                    wrote on last edited by
                    #10

                    So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)

                    Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                    L C 2 Replies Last reply
                    0
                    • S Stuart Dootson

                      So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)

                      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                      L Offline
                      L Offline
                      led mike
                      wrote on last edited by
                      #11

                      Stuart Dootson wrote:

                      lambdas are available

                      Yeah, I suppose that's a good thing, we'll see.

                      1 Reply Last reply
                      0
                      • S Stuart Dootson

                        So it is (Boost.Bind equivalent, that is)! Well, you learn something new every day! So, come VS2010, when C++0x lambdas are available, I'll be well happy :-)

                        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                        C Offline
                        C Offline
                        CPallini
                        wrote on last edited by
                        #12

                        Stuart Dootson wrote:

                        Well, you learn something new every day!

                        Get in times Stuart! ;P of course I knew nothing about... :rolleyes:

                        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                        [My articles]

                        1 Reply Last reply
                        0
                        • C CPallini

                          Why do you want to follow a very plain-C path? You know, C++ is a fully featured OOP launguage. :)

                          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                          [My articles]

                          A Offline
                          A Offline
                          Arsalan Malik
                          wrote on last edited by
                          #13

                          You are right, thanks, perhaps I am thinking too much in C :-D

                          ARSALAN MALIK

                          1 Reply Last reply
                          0
                          • S Stephen Hewitt

                            Firstly, your approach using void (*display)(char*); doesn't work as it points to a global or static class member function, not a member function. One way to to do it is the following, assuming the function to be called is always display:

                            1. Define an interface that contains the function:

                              class ICallable
                              {
                              public:
                              virtual void display(char *msg) = 0;
                              };

                              Note the function is a pure virtual function.

                            2. Derive the classes that have the function to be called from it:

                              class A : public ICallable
                              {
                              public:
                              virtual void display(char *msg)
                              {
                              // A's impelentation here...
                              }
                              };

                            3. Your pointer now looks like the following:

                              ICallable *pPointer;

                            4. The call through the pointer like this:

                              pPointer->display("Hello world!");

                            Steve

                            A Offline
                            A Offline
                            Arsalan Malik
                            wrote on last edited by
                            #14

                            Thanks a lot for the hint, perhaps I was thinking too much in C :-D

                            ARSALAN MALIK

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups