Thread: Pointers to Class Functions

  1. #1
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401

    Pointers to Class Functions

    I'm trying to send a pointer to a class function to another class for execution. Here's an example:
    Code:
    class B
    {
    public:
    	void DoThis(int num, bool (*p2Func)(std::ofstream&));
    private:
    	std::ofstream m_fileOut;
    };
    
    void B::DoThis(int num, bool (*p2Func)(std::ofstream&))
    {
    	(*p2Func)(m_fileOut);
    }
    
    class A
    {
    public:
    	A() {m_pB = new B();}
    	~A() {delete m_pB;}
    	bool Serialize(std::ifstream& ar) {return true;}
    	bool Serialize(std::ofstream& ar) {return true;}
    	void DoSomethingElse();
    private:
    	B* m_pB;
    };
    
    void A::DoSomethingElse()
    {
    	//do some stuff
    	m_pB->DoThis(0,Serialize);
    }
    I get the following compiler error:
    error C2664: 'DoThis' : cannot convert parameter 2 from 'bool (std::ofstream &)' to 'bool (*)(std::ofstream &)'
    None of the functions with this name in scope match the target type

    When I try changing the call to DoThis to:
    Code:
    	m_pB->DoThis(0,&Serialize);
    I get the following compiler error:
    error C2276: '&' : illegal operation on bound member function expression

    I'm not exactly sure what I'm doing wrong. Can someone point me in a better direction?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  2. #2
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Making Serialize() a static function would work, I think. Otherwise, if you're trying to make m_pB's DoThis() execute (calling 'A' object)->Serialize(), you'll probably have to pass m_pB either a functor or else this and a pointer-to-member-function (syntax is slightly different).

    **EDIT**
    From what your functions do, it looks like the static solution would work. If it isn't static, then the function looks for an additional (hidden) parameter, the this pointer of the object. Since Serialize() seems to act very much like a global function (but stuck within a class for organization's sake?), you can get away with removing the this pointer by declaring it static, in effect making it an ordinary global function.
    Last edited by Hunter2; 03-23-2005 at 01:23 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #3
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    I think my example was a little too simple. I can't make Serialize a static function because Serialize makes use of other class members that are not static.
    Quote Originally Posted by Hunter2
    you'll probably have to pass m_pB either a functor or else this and a pointer-to-member-function (syntax is slightly different).
    I've been using http://www.newty.de/fpt/index.html as a reference for function pointers. I'll take a look at functors and see if I can wrap my head around it. What is this other syntax for passing this and a pointer-to-member-function?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  4. #4
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Thanks for the help, Hunter2. A functor looks like what I needed. I ended up with the following test code:
    Code:
    #include <iostream>
    #include <string>
    
    using std::cout;
    using std::endl;
    using std::string;
    
    // abstract base class
    class ISPrintFunctor
    {
    public:
    	virtual void operator()(const char * ar) = 0;
    };
    
    // derived template class
    template <class T>
    class ISPrintSpecificFunctor : public ISPrintFunctor
    {
    private:
    	void (T::*m_p2Func)(const char *);
    	T* m_pObj;
    public:
    	ISPrintSpecificFunctor(T* pObj, void(T::*p2Func)(const char *))
    		: m_pObj(pObj), m_p2Func(p2Func) {};
    	
    	virtual void operator()(const char * ar)
    		{
    			(*m_pObj.*m_p2Func)(ar);
    		};
    };
    
    class B
    {
    public:
    	B(const string& a) : m_a(a) {}
    	void DoThis(int num, ISPrintFunctor* functor)
    		{
    			(*functor)(m_a.c_str());
    		};
    private:
    	string m_a;
    };
    
    class A
    {
    public:
    	A(string a)
    		{
    			m_pB = new B(a);
    		}
    	~A()
    		{
    			delete m_pB;
    		}
    	void DoSomethingElse()
    		{
    			//do some stuff
    			ISPrintSpecificFunctor<A> functor(this,&A::Print);
    			m_pB->DoThis(0,&functor);
    		};
    	void Print(const char * ar)
    		{
    			cout << ar << endl;
    		};
    private:
    	B* m_pB;
    };
    
    // main program
    int main()
    {
    	A a("Hello World!");
    	a.DoSomethingElse();
    	
    	return 0;
    }
    Certainly a warped way to Hello World, but it works. As a side note, you can make Print a private member of class A and it will still work. Doesn't that violate encapsulation? Once again, thanks for the help.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    The functor is an extra level of indirection that you may not need...
    Here's what you wanted to do originally, but didn't have the syntax quite right:
    Code:
    #include <iostream>
    #include <string>
    
    using std::cout;
    using std::endl;
    using std::string;
    
    class B
    {
    public:
        B(const string& a) : m_a(a) {}
        
        template <class T>
        void DoThis(T* pObj, void(T::*p2Func)(const char *))
        {
            (pObj->*p2Func)(m_a.c_str());
        }
    
    private:
        string m_a;
    };
    
    class A
    {
    public:
        A(const string &a) {m_pB = new B(a);}
        ~A() {delete m_pB;}
    
        void DoSomethingElse()
        {
            m_pB->DoThis(this, &A::Print);
        }
    
        void Print(const char * ar)
        {
            cout << ar << endl;
        }
        
    private:
        B *m_pB;
    };
    
    int main()
    {
        A a("Hello World!");
        a.DoSomethingElse();
        
        return 0;
    }
    gg

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    And thus, both methods have been demonstrated pretty much exactly as I had envisioned them I ordinarily would use the 'this and pointer-to-member-function' approach, but syntactically the functor approach looks nicer once all the appropriate templates and classes have been created (all necessary information contained in a single object rather than being passed in pieces - nice if the functor will be shuffled around a bit before use), and has the benefit of (perhaps) better swappability with ordinary function pointers for later code reuse.
    Last edited by Hunter2; 03-23-2005 at 11:06 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Quote Originally Posted by 7stud??
    In three sentences or less, can someone explain what is meant by a call back function?
    It's a user-specified function, usually set via a function pointer, that gets called by the inner workings of an independent module when a given event occurs.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by Hunter2
    It's a user-specified function, usually set via a function pointer, that gets called by the inner workings of an independent module when a given event occurs.
    lol, how in the world did you manage to post in the wrong thread?
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  9. #9
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I don't know. I got an email from CBoard saying 7stud replied to THIS thread, with THAT question. Hence the "??" in the quote name

    Quote Originally Posted by CProg Notifier Email
    Hello Hunter2,

    7stud has just replied to a thread you have subscribed to entitled - Pointers to Class Functions - in the C++ Programming forum of C Board.

    This thread is located at:
    http://cboard.cprogramming.com/showt...4&goto=newpost

    Here is the message that has just been posted:
    ***************
    Hi,

    Every time I see the term call back function, my eyes glaze over, and I know I no longer really understand what the author is talking about.

    In three sentences or less, can someone explain what is meant by a call back function?

    Thanks.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  2. Replies: 10
    Last Post: 07-26-2008, 08:44 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Class function pointers
    By VirtualAce in forum C++ Programming
    Replies: 40
    Last Post: 02-17-2005, 12:55 AM
  5. DLL class member functions
    By nickname_changed in forum C++ Programming
    Replies: 1
    Last Post: 07-11-2003, 06:59 AM