Thread: Method pointers and inheritance

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Method pointers and inheritance

    I came across a scenario where I need to register class methods from a subclass, however the calls to Register below (obviously) complains about converting wrong types (CSub:: instead of CBase:.
    Code:
    class CBase;
    
    typedef void (CBase::*Pointer)();
    
    class CBase
    {
      public:
        void Register(Pointer P);
    };
    
    class CSub : public CBase
    {
      public:
        void Method1();
        void Method2();
        void Method3();
    };
    
    CSub Sub;
    
    Sub.Register(&CSub::Method1);
    Sub.Register(&CSub::Method2);
    Sub.Register(&CSub::Method3);
    I could of course use plain functions (static methods) and pass a class objects but that wouldn't be very elegant. Is there a correct way to solve this? What happens if I perform a reinterpret_cast?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    hmm after a quick bit of research, I've found you can't actually do this, then I found a whole bunch of stuff I NEVER wanted to know about pointer-to-member-functions (i.e. depending on platform, inheritance, virtual-ity, etc they can be anywhere from 4 to 16 bytes!)

    Happily there is a way around this. before I show you the code, I'll briefly explain the pros and cons of my method
    Pros:
    - it's way more flexible. you can pass ANY method of a class, even ones that require arguemetns.

    cons:
    - it requires boost::bind. you should have this installed anyway, so view this as an oppurtunity.
    - it's a little more complicated
    - there's a slight runtime cost.
    Code:
    #include <boost/bind.hpp>
    
    class FBase
    {
    };
    
    template <typename FUNC>
    class functor : public FBase
    {
    public:
    	functor(FUNC f)
    	: m_f(f) 
    	{}
     
    	void operator()(void)
    	{
    		m_f();
    	}
    
    private:
    	FUNC m_f;
    };
    
    template <typename FUNC>
    functor<FUNC> make_functor(FUNC f)
    {
    	return functor<FUNC>(f);
    }
    
    class CBase
    {
    public:
    	void Register(FBase &f);
    
    };
    
    class CSub : public CBase
    {
    public:
        void Method1();
        void Method2();
        void Method3();
    };
    
    int main()
    {
    	CSub sub;
    
    	sub.Register(make_functor(boost::bind(CSub::Method1, sub)));
    }
    obviously that's not complete. there are memory leaks and so on, that you need to fix, but I'll leave that as an exercise for the reader (always wanted to say that )
    "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?

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    Another possible approach is each derived class keeps a seperate function pointer. Access via virtual function.

    Kuphryn

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    depending on how the classes are set up, you may be able to use a template function:

    Code:
    class CBase
    {
    public:
    	template <class F>
            void Register(F f);
    };
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

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. on method pointers and inheritance
    By BrownB in forum C++ Programming
    Replies: 2
    Last Post: 03-02-2009, 07:50 PM
  4. Unions and void pointers
    By dwks in forum C Programming
    Replies: 11
    Last Post: 09-05-2007, 11:59 AM
  5. Displaying pointer's actual values in inheritance
    By Poof in forum C++ Programming
    Replies: 14
    Last Post: 07-29-2004, 07:34 AM