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.
"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
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.
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 ?
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 !!)
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.
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.
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 ...
#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.
Bookmarks