Thread: on method pointers and inheritance

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    106

    on method pointers and inheritance

    Hello everybody.

    My project is composed by some dialogs of base type CMyDlg which receives characters and manages them by a function "OnCharReceived" called by the environment upon char generation/reception. Each derived dialog can perform different actions on Char reception:

    Code:
    class CMyDlg:public CDialog
    {
    public:
      CMyDlg():CDialog(){};
      BOOL OnCharReceived( CHAR c){ return (*m_pcurrentCharHandler)( c );  }
    
    protected:
      virtual BOOL privCharHandler( CHAR c );
      BOOL (CMyDlg::*m_pcurrCharHandler)(CHAR c );
      
    }
    
    class CMyDlgOne:public CMyDlg
    {
    public:
      CMyDlgOne():CMyDlg(){}
    
    private:
      BOOL privCharHandler( CHAR c );  //overridden method
      BOOL privCharHandler_2( CHAR c); //new method
    }
    What I want to do is to programmatically set "m_pcurrCharHandler" to change the "CharHandler" function from a method inside the CMyDlgOne class. Let's say that, if I receive 'Z' I want all the next chars to be handled by privCharHandler_2:
    Code:
    BOOL CMyDlgOne::privCharHandler( CHAR c)
    {
      if( c == 'z' )
        m_pcurrCharHandler = privCharHandler_2;
    
      return TRUE;
    }
    Also, if a derived class does not override "privCharHandler()", I want that it can use the function of the base class:
    Code:
    class CMyDlgTwo: public CMyDlg
    {
    public:
      //some methods, not important
    
    private:
      BOOL privCharHandler_3( CHAR c); //new method
    }
    
    
    BOOL CMyDlgTwo::OnCharReceived( CHAR c)
    {
      if( c == 'z' )
        m_pcurrCharHandler = privCharHandler_3;     //new method
      else
        m_pcurrCharHandler = privCharHandler;	//base class method
    
      return (*m_pcurrCharHandler)(c);
    }
    Is there a way todo this? If yes, how do you write correctly the code to use the method pointer? If not, is there another way to do a "prigrammatically" change of working function? I'm thinking about state variables, and then "switch()" on their value to do different things, but I'd like something more flexible I think.

    Thank you for any hint and correction.

    BrownB

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There may be some way to make the compiler do this using casts, but it is likely to be an "easily broken" solution. The reason being that all member functions take a hiddn "<own class>* this" parameter as part of the function call. Of course, if you have a derived class, the member function expects to see a pointer to the new class, not the older style class.

    Is there not some way that you can hide this functionality in a static function (those do not have the hidden "this" parameter - you can then explicitly pass the base-class member pointer as a parameter).

    Or perhaps virtual methods would be a better solution?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    I would think that this could be solved using templates also. Here's an example of how to use templates to do this:

    Code:
    #include <iostream>
    
    template <typename SubclassT>
    class C1 
    {
    public:
        typedef C1<SubclassT> self_type;
        typedef SubclassT class_type;
    
        typedef bool (class_type::*callback_type)(int);
    
        C1() : fn_(0) { }
        void set_callback(callback_type fn) { fn_ = fn; }
        bool fire_callback(int param) { return (static_cast<class_type*>(this)->*fn_)(param); }
    
    private:
        callback_type fn_;
    };
    
    
    class C2 : public C1<C2>
    {
        public:
            C2() { set_callback(&C2::my_callback); }
    
            bool my_callback(int param) 
            {
                bool ret = param == 4;
                set_callback(&C2::my_callback_2);
                return ret;
            }
    
            bool my_callback_2(int param) 
            {
                bool ret = param == 2;
                set_callback(&C2::my_callback);
                return ret;
            }
    
    };
    
    int main()
    {
        C2 f;
        std::cout << "Call 1: " << f.fire_callback(4) << std::endl
                  << "Call 2: " << f.fire_callback(4) << std::endl
                  << "Call 3: " << f.fire_callback(2) << std::endl
                  << "Call 4: " << f.fire_callback(2) << std::endl;
        return 0;
    }
    Prints:
    Call 1: 0
    Call 2: 1
    Call 3: 1
    Call 4: 0

    Hopefully something similar in nature would work for you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 06-08-2009, 03:03 PM
  2. Issue with pointers to an abstract class and inheritance
    By bainevii in forum C++ Programming
    Replies: 2
    Last Post: 03-31-2009, 07:51 AM
  3. Unions and void pointers
    By dwks in forum C Programming
    Replies: 11
    Last Post: 09-05-2007, 11:59 AM
  4. Method pointers and inheritance
    By Magos in forum C++ Programming
    Replies: 3
    Last Post: 04-05-2006, 06:43 PM
  5. Displaying pointer's actual values in inheritance
    By Poof in forum C++ Programming
    Replies: 14
    Last Post: 07-29-2004, 07:34 AM