-
September 20th, 2010, 05:24 AM
#1
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.
-
September 20th, 2010, 06:07 AM
#2
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
-
September 20th, 2010, 06:23 AM
#3
Re: call derived method from base class
sorry I updated the post, it's actually Base::go()
-
September 20th, 2010, 07:27 AM
#4
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.
-
September 20th, 2010, 07:36 AM
#5
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 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.
-
September 20th, 2010, 01:46 PM
#6
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
-
September 20th, 2010, 01:52 PM
#7
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.
-
September 21st, 2010, 09:09 AM
#8
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 !!)
-
September 21st, 2010, 09:16 AM
#9
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.
-
September 21st, 2010, 10:40 AM
#10
Re: call derived method from base class
Originally Posted by Lindley
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 ...
-
September 21st, 2010, 12:10 PM
#11
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
-
September 21st, 2010, 12:41 PM
#12
Re: call derived method from base class
Originally Posted by let_me_in
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.
-
September 22nd, 2010, 04:18 AM
#13
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.
-
September 22nd, 2010, 04:40 AM
#14
Re: call derived method from base class
Originally Posted by let_me_in
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 ...
-
September 22nd, 2010, 05:23 AM
#15
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
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|