call derived method from base class
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17

Thread: call derived method from base class

  1. #1
    Join Date
    Feb 2010
    Posts
    10

    call derived method from base class

    Hi All,

    I'm having troubles achieving something, I need to call an overriden method from the base class as follow :
    Code:
    class Base{
    	public: 
    		void start(){
    			new thread(boost::bind(&Base::run, this));
    		}
    		
    		virtual void go(){
    			// do something
    		}
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
     
    	return 0;
    }
    I thought this way the binding is done at runtime, and the method of the base class is called but this is not what I'm getting !!

    Just to discard the boost::bind, I tried this as well :

    Code:
    class Base{
    	public: 
    		void start(){
    			new thread(boost::ref(*this));
    		}
    		
    		virtual void go(){
    			//do something.
    		}
    		
    		void operator()(){
    			this->go();
    		}
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
     
    	return 0;
    }
    OS : windows
    COMPILER : gcc

    am I doing something wrong ?

    thanks in advance.

    BR
    Last edited by let_me_in; September 20th, 2010 at 06:23 AM.

  2. #2
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,725

    Re: call derived method from base class

    I see no definition of Base::run?
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  3. #3
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    sorry I updated the post, it's actually Base::go()

  4. #4
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    ok, now it's driving me crazy, if I do :

    Code:
    class Base{
    	public: 
    		void start(){
    			new thread(boost::bind(&Base::go, this));
    		}
    		
    		virtual void go(){
    			// do something
    		}
    
                    string print(){
                           return "something";
                    }
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
            std::cout << der->print();
     
    	return 0;
    }
    it actually works, but if I remove the std::cout << der->print(); from the main, it will not !!!

    any guru that can explain this ? is this a bug in gcc ?
    Last edited by let_me_in; September 21st, 2010 at 12:01 PM.

  5. #5
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,297

    Re: call derived method from base class

    When you write "&Base::run", you are making a direct call to Base::run, bypassing the entire virtual mechanism, and calling BAse::run regardless of the type of this. Use the "non virtual interface calls a virtual implementation" design:

    Code:
    class Base{
        public:
            void start(){
                new thread(boost::bind(&Base::run, this));
            }
    
            void run(){
                //run is called directly
                this->go(); //now go is called virtually
            }
    
            string print(){
               return "something";
            }
            
        private: //yes private
            virtual void go(){
                // do something
            }
     
    }
     
     
    class Derived : public Base {
        private: //yes private
            void go(){
                //do something different
            }
    }
     
     
    int main(int argc, char** argv){
        Derived* der = new Derived();
        der->start();
            std::cout << der->print();
     
        return 0;
    }
    [/code]
    Is your question related to IO?
    Read this C++ FAQ LITE 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.

  6. #6
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    Hi monarch_dodra,

    actually it's working, even with the first version I posted, the problem comes from using boost::thread or boost::bind, if I remove it and replace it with a simple this->run, it'll work.

    now what I really want to konw, is why does it work normally when I add the call to print in the main ? do you have an idea ?

    thanks again

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,888

    Re: call derived method from base class

    Because in one situation the virtual function call mechanism is suppressed, and in the other it is not. Simple.

  8. #8
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    Hello Lindley,

    how is that happening, is there a rule ?

    it doesn't make sense, since the class definition is the same in both situations, the difference is how I'm using the class (if I add a call to the print member method, it will work, if I remove the call, it simply won't !!)

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,888

    Re: call derived method from base class

    If you call the method via a function pointer or class method pointer, you lose polymorphism. That's just the way it works.

    The way around this is to instead call another function which in turn calls the specified method "normally", so that the virtual function call dispatch can work. This is what monarch_dodra was demonstrating above.

  10. #10
    Join Date
    Oct 2008
    Posts
    1,137

    Re: call derived method from base class

    Quote Originally Posted by Lindley View Post
    If you call the method via a function pointer or class method pointer, you lose polymorphism. That's just the way it works.

    that's not true; member function pointers preserve polymorphism. For example,

    Code:
    struct Base
    {
    	virtual void run() { std::cout << "1" << std::endl; }
    };
    
    struct Derived: Base
    {
    	virtual void run() { std::cout << "2" << std::endl; }
    };
    
    int main()
    {
    	typedef void(Base::*FunctionType)();
    
    	FunctionType ptr = &Base::run;
    	Base b;
    	Derived d;
    
    	(b.*ptr)(); // prints 1
    	(d.*ptr)(); // prints 2
    }
    that said, the OP has provided only bogus non compiling code, so it's difficult to say more ...

  11. #11
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    hi superbonzo,

    the code from post 4 compiles fine, just include boost::thread and boost::bind,

    my question is : what is happening when I include der->print() in the main that makes it work (even with boost::thread) !!

    ps : the problem comes from boost::thread, if I remove it the virtual mechanism works just fine

    BR

  12. #12
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,888

    Re: call derived method from base class

    Quote Originally Posted by let_me_in View Post
    the code from post 4 compiles fine, just include boost::thread and boost::bind,
    Well, quite aside from the main question, there are two problems with post #4's code which should be fixed:

    1) You use new without a corresponding delete. This is never acceptable even in the most trivial of test programs....especially since the relevant functionality could be tested without using new at all, by just putting "der" on the stack.

    2) You do not wait for the thread to exit before reaching the end of main(), so you are not guaranteed that it will ever run before the program finishes.

  13. #13
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    Hi Lindley,

    in my real code, I've those two problems fixed, I just ommited them to shorten the code a little bit.

  14. #14
    Join Date
    Oct 2008
    Posts
    1,137

    Re: call derived method from base class

    Quote Originally Posted by let_me_in View Post
    in my real code, I've those two problems fixed, I just ommited them to shorten the code a little bit.
    and how are we supposed to see what happens in the code you've not shown us ? post the minimal complete correct code that reproduce the problem, along with your observed and expected program behavior ...

  15. #15
    Join Date
    Feb 2010
    Posts
    10

    Re: call derived method from base class

    Hello all,

    here is a code that reproduces the error :
    Code:
    #include <boost/thread.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
    
    class Base1{
        public:
    
            virtual ~Base1(){myThread->join();}
            void start(){
                myThread = new boost::thread(boost::bind(&Base1::go, this));
            }
    
            virtual void go(){
                std::cout<<"Base"<<std::endl;
            }
    
    
            boost::thread* myThread;
    
    
    
    };
    
    
    class Derived1 : public Base1 {
        public:
            void go(){
                std::cout<<"Derived"<<std::endl;
            }
    };
    
    
    int main(int argc, char** argv){
        Derived1* der = new Derived1();
        der->start();
    
        delete der;
        //der->myThread->join();
    
        return 0;
    }
    now I know where the problem is, it's in the destructor, if you remove the "delete der;" from the main and replace it with "der->myThread->join();" it will work.

    hope someone can tell me why

    BR

Page 1 of 2 12 LastLast

Posting Permissions

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


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center