CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Sep 2010
    Posts
    1

    Pointer to member function inheritance rules?

    Hi everybody;

    Member function pointer inheritance rules have been unclear to me, and several books that I have only make it muddier.

    I tried last year to make a standard queue for processing function calls for my brood of objects. But I gave up when I found that that I could not use a base class function pointer an abstraction, although the signatures match for derived classes. This is a pretty simple illustration:

    class AA {
    public:
    virtual int ff( const char* me ) { }
    void assign( int (AA::*fPtr)(const char*) ) { }
    };

    class BB : public AA {
    public:
    int ff( const char* me ) { }
    void assign( int (BB::*fPtr)(const char*) ) { }
    };

    int
    main( int argc, char* argv[] )
    {
    AA a;
    BB b;

    a.assign( &AA::ff );
    a.assign( &BB::ff );
    return 0;
    }

    cc -o fp fp.cxx -lstdc++
    fp.cxx: In function 'int main(int, char**)':
    fp.cxx:33: error: no matching function for call to 'AA::assign(int (BB::*)(const char*))'
    fp.cxx:12: note: candidates are: void AA::assign(int (AA::*)(const char*))

    http://www.codeproject.com/KB/cpp/FastDelegate.aspx
    says: "Member function pointers have a horrible restriction: they can only point to member functions of a single class."

    This has been my experience. For racking and stacking various functions in an inheritance tree, pointers-to-member functions are pretty much useless. We were driven to use static functions for everything, esp. since static functions will inter-mingle with C functions. Our lib is very fast also. Given that I understand that member function pointers are often sizeof()x3 bigger than their static equivs and are hence non-interchangeable, I still want to know: Is this lack of inheritance in pointers-to-member-functions a religion thing (they are all the same size and lay out their args the same), or is there a technical reason that such a useful tool (IMHO is not allowed? Thanks ALOT...

    me

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Pointer to member function inheritance rules?

    I don't know much about this, but I'd be very curious to see what this did:
    Code:
    class AA {
    public:
        virtual int ff( const char* me )  = 0;
        void assign( int (AA::*fPtr)(const char*) ) { fPtr("AA"); }
    };
    
    class BB : public AA {
    public:
        int ff( const char* me ) { cerr << me; }
        void assign( int (AA::*fPtr)(const char*) ) { fPtr("BB"); }
    };
    
    int
    main( int argc, char* argv[] )
    {
    BB b;
    
    b.assign( &AA::ff );
    return 0;
    }
    In other words, will a pointer to a pure virtual member function (a) be allowed and (b) properly invoke the derived implementation for the given object?

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Pointer to member function inheritance rules?

    Some corrections:
    Code:
    #include <iostream>
    
    class AA {
    public:
        virtual int ff( const char* me )  = 0;
        void assign( int (AA::*fPtr)(const char*) ) { (this->*fPtr)("AA"); }
    };
    
    class BB : public AA {
    public:
        int ff( const char* me ) { std::cerr << me; return 0; }
        void assign( int (AA::*fPtr)(const char*) ) { (this->*fPtr)("BB"); }
    };
    
    int main( int argc, char* argv[] )
    {
        BB b;
        b.assign( &AA::ff );
        return 0;
    }
    
    Output:
    BB
    This is using Visual Studio 2010.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Pointer to member function inheritance rules?

    The problem is that the virtual mechanism is carried by objects, not functions. When you start using function pointers, the pointers can point only to 1 function, and that's it.

    What you can do is use the "non virtual interface to virtual implementation" design thingy, where a non-virtual interface function calls a private virtual one:

    Code:
    class AA {
    public:
        //ff dispatches polymorphically to _ff
        int ff( const char* me )
        {
            this->_ff(me);
        }
        void assign( int (AA::*fPtr)(const char*), const char* me )
        {
            (this->*fPtr)(me); //calls the delegate function. In this case, it is AA::ff
                               //but it could be anything else
        }
    
    private:
        virtual int _ff( const char* me )
        {
            std::cout << "hello from AA::ff: " << me << std::endl;
        }
    };
    
    class BB : public AA {
    public:
    
    private:
        virtual int _ff( const char* me )
        {
            std::cout << "hello from BB::ff: " << me << std::endl;
        }
    };
    
    int main( int argc, char* argv[] )
    {
        //Get base function pointer. But we'll get the corresponding derived function.
        int (AA::*fPtr)(const char*) = &AA::ff;
    
        //Create objects
        AA* a = new AA;
        AA* b = new BB;
        a->assign( fPtr, "hi" );  //calls AA::_fptr("hi")
        b->assign( fPtr, "ho" ); //calls BB::_fptr("ho")
        return 0;
    }
    Is this the behavior you want? If it isn't, then I'm confused.

    The overhead is 1 function call (since you are using function pointers) + 1 virtual dispatch. I doubt there could be a much faster design.

    This design is not overly complicated either, so you should be able to adapt it without a full re-structure.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured