pure virtual method called in thread of concrete class - c++

I have a problem with virtual methods in C++ on a multithreading context (Linux).
This next example points out my problem:
class Base {
};
class Concrete1: public Base { //define pure virtual function
virtual void func() = 0;
};
class Concrete2: public Concrete1 { //override of virtual func
void func() {}
void run(){
//....
pthread_create(&handle, NULL, Concrete2::thread, static_cast<void*>(this));
}
static void* thread(void arg*){
Concrete2 *ptr = static_cast<Concrete2*>(arg);
//Concrete1 *ptr = static_cast<Concrete2*>(arg); // same error
while(1){
//....
ptr->func()
}
}
};
int main(){
Concrete2 obj;
obj.run();
pthread_exit(NULL);
return 0;
}
When the line ptr->func() is executed, the following error appears:
pure virtual method called terminate called without an active exception
Can someone tell me why the pure virtual method is being called instead of the overrided method?

Concrete2 is created on the stack and is destroyed as soon as run is called.
The spawned thread does not keep obj alive.
Your thread function is trying to dereference a destroyed object, aka a dangling pointer, which constitutes undefined behavior.

Related

How to manage thread resource with polymorphism? (C++)

I am trying to implement polymorphism, where the derived class implements a method that is run in a separate thread:
#include <memory>
#include <thread>
#include <chrono>
class Base
{
public:
std::thread m_jobThread;
~Base() { if (m_jobThread.joinable()) m_jobThread.join(); }
virtual void doJob() = 0;
void doJobInBackground() { m_jobThread = std::thread(&Base::doJob, this); }
};
class Drived : public Base
{
public:
Drived() = default;
virtual void doJob() final { std::this_thread::sleep_for(std::chrono::seconds(1)); }
};
int main(int argc, char const *argv[])
{
Drived d;
d.doJobInBackground();
return 0;
}
How do I achieve this safely without getting a pure virtual method called exception?
I want to be able to destroy the derived objects, potentially while the job is happening and have the destructor of the base class deal with managing the thread. but since the vtable of the derived class gets destroyed before the destructor of the base class is run, I get a pure virtual method exception.
I thought of adding a stop method in the destructor of the derived class that makes sure the thread is joined. But that defeats the purpose of my polymorphic design, where I want the derived class to ONLY be responsible for defining the doJob method and not for directly or indirectly handling the resources of the base class such as the thread...
Any ideas if this is possible? Do I need to change my design?
As pointed out by Sam Varshavchik in his comment above, the reason why you trigger a pure virtual function call here is that the destructor of d is run before your second thread has even started executing. You only synchronize in the Base destructor. By the time the Base destructor runs, however, the Derived part of the object has already been destroyed. The dynamic type of the object at this point is just Base, because that's all that's still alive and, thus, the virtual function call dispatches to the base version, which is pure. Strictly speaking, you actually have undefined behavior here because the object being destroyed in one thread while another may be calling a method on it violates [basic.life]/7.2. The lifetime of your object ends when the destructor call starts [basic.life]/1.3, the method call in the second thread does not inter-thread happen before the destructor call in the first thread…
Just
#include <thread>
#include <chrono>
class Base
{
std::thread m_jobThread;
public:
void join() { if (m_jobThread.joinable()) m_jobThread.join(); }
virtual void doJob() = 0;
void doJobInBackground() { join(); m_jobThread = std::thread(&Base::doJob, this); }
};
class Derived : public Base
{
public:
virtual void doJob() final { std::this_thread::sleep_for(std::chrono::seconds(1)); }
};
int main(int argc, char const* argv[])
{
Derived d;
d.doJobInBackground();
d.join();
return 0;
}
works fine…

Unexpected Output...how function binding happens in virtual table

class Base
{
public:
int a;
virtual void fun1()
{
cout<<"Hello Base"<<endl;
}
void fun2()
{
fun1();
}
};
class Derived: public Base
{
int a;
void fun1()
{
cout<<"Hello Derived"<<endl;
}
};
int main()
{
Base * B = new Derived;
B->fun2();
return 1;
}
Please help me understand why output is Hello Derived.How this function binding takes place.How is virtual table entry created for Base and derived class.
The virtual table is created when the class objects are constructed. When you construct a Derived object, it will first call the Base constructor (which creates the vtable and writes its own Base::fun1 into that. Then the Derived constructor runs and overwrites the vtable entry for fun1 with its own implementation (Derived::fun1).
If you then, at any later point (even from within any Base function) call fun1 of such an object instance, it will look into the vtable and call whatever function it finds there. As explained above, it is Derived::fun1 that is in the vtable of a Derived object after construction, so this is the one that will get called. It doesn't matter that you are currently in a Base function, the vtable entry does not change.
Note that during construction, the vtable is not fully set up: If you were to call fun1 from within the Base constructor, you would not call Derived::fun1 but Base::fun1 because Derived did not replace the vtable entries yet.
Also note that fully specifying the function (e.g. calling Base::fun1() on a Derived instance) will not do a vtable lookup but instead use exactly the specified function.
The pseudo code looks like this:
#include <iostream>
class Base{
protected:
void **vt_ptr;
public:
int a;
//Executed prior to base member initialization
//and reexecuted prior to Base destructor call
void set_dynamic_type(){
vt_ptr = Base::vtable;
}
/*virtual*/
void fun1(){
reinterpret_cast<void(*)(Base&)>(vt_ptr[1])(*this);
}
void fun2(){
fun1();
}
private:
static void func1_def(Base& pseudo_obj_arg){
Base* this=&pseudo_obj_arg;
std::cout<<"Hello Base"<<std::endl;
}
static void* vtable[2];
};
void* Base::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Base),
reinterpret_cast<void*>(&Base::func1_def)};
class Derived: public Base
{
int a;
//Executed after Base intialization,
//before Derived member initialization.
//Reexecuted prior to Derived destructor call
void set_dynamic_type(){
Base::vt_ptr = Derived::vtable;
}
private:
static void func1_def(Base& pseudo_obj_arg){
Derived* this=static_cast<Derived*>(&pseudo_obj_arg);
std::cout<<"Hello Derived"<<std::endl;
}
static void* vtable[2];
};
void* Derived::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Derived),
reinterpret_cast<void*>(&Derived::func1_def)};
Also a qualified call as in: obj.Base::func1() directly calls Base::func1_def(obj), otherwise it goes throw the devirtualization process described in Base::func1.

Calling a pure virtual function in a separate thread that is created from base-class constructor

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
class Base {
protected:
pthread_t receiverThreadID;
Base() {
pthread_create(&receiverThreadID,NULL,threadFunction,this);
}
~Base() {
}
virtual void handleEvent() = 0;
static void* threadFunction(void* arg) {
while(true) {
// This threads receives UDP via recvfrom(). The messages can come in randomly. I use sleep() to simulate a blocking wait
sleep(1);
((Base*)arg)->handleEvent();
}
return 0;
}
};
class Derived : public Base {
virtual void handleEvent() {
// Do something
printf("hello\n");
}
public:
Derived() {}
~Derived() {}
};
int main() {
Derived derived;
sleep(10);
}
You are not supposed to call a pure virtual function from the constructor of a class, but is it ok to create a thread in the constructor, that in turn calls a pure virtual function? Is there any risk for a race condition? I did not get any runtime errors with the code above.
If it is not ok to code like I've done, how should you solve it?
This can blow up if the threadFunction() calls handleEvent() before the constructor of Derived is done.
Why not place the pthread_create call in another function - say, start() - and call it once the object is constructed?
class Base {
protected:
pthread_t receiverThreadID;
Base() {}
~Base() {}
void start() {
pthread_create(&receiverThreadID,NULL,threadFunction,this);
}
...
};
If you call it in a thread or directly doesn't matter, you should not call the pure virtual function before Derived is fully constructed - and this happens after the construction of Base.
Your sleep is what makes this code running, but not safe.
If you want a safe version, i see 2 options:
Use mutexes or similar mechanisms to prevent the thread from calling the function before the constructor is done.
(And thats probably the better option): Start your thread in a function called after the constructor. You might want to utilize a factory-function here to make sure it is always called.
It is wrong to call virtual function when the constructor is not completely executed.
As other suggested, please make sure to have another function that used this virtual function. And call this function once object is created.
eg.
class Base{
static void *create_thread(void * arg){
pthread_create(&receiverThreadID,NULL,threadFunction,this);
}
};
// client call something like this.
Base * b = new Derived();
b->create_thread();
Hope this should solve the problem.

Perform operations BEFORE calling destructor in C++ QObject subclass

I have a class hierarchy which inherits QObject.
I need to perform some operations after construction (when the object is fully constructed) and before destruction (when the object is still complete).
The construction part is no problem, since I can control the construction of an object, making private its constructor and just making public the creator function which already can perform all the required operations.
The problem comes with the destructor. I have done more or less the same: hiding the destructor and providing a destroyer function which performs all the operations and then destroys the object.
Here is where the problem begins:my class hierarchy is used as part of the QJSEngine scripting module, which takes ownership of all the objects, and when it is time, it destroys them using the QObject's destructor, thus, bypassing my destroyer function. It is of no help declaring my destructors private, since the QJSEngine can always execute the QObject's destructor (and by the way, also can any piece of code which casts my pointers to QObject).
I require to perform this operations before calling the destructor, since I use some virtual functions, so I need to execute this BEFORE beginning the destruction process, so the virtual functions calls will not fail.
Is there a way to achieve this?
I attach a basic code snipped showing my problem:
class IBase: public QObject {
public:
template<typename T>
static IBase * create() {
IBase * obj=new T;
obj->afterConstruction();
return obj;
}
void destroy() {
this->beforeDestruction();
delete this;
}
protected:
IBase(): fBeforeDestruction(false){}
virtual ~IBase(){
//Try to perform operations, but it is too late....
if (!fBeforeDestruction)
doBeforeDestruction();
}
virtual void doAfterConstruction(){}
virtual void doBeforeDestruction(){}
private:
bool fBeforeDestruction;
void afterConstruction() {
doAfterConstruction();
}
void beforeDestruction(){
fBeforeDestruction=true;
doBeforeDestruction();
}
};
class TSubclass: public IBase {
protected:
TSubclass(){}
virtual ~TSubclass(){}
virtual void doAfterConstruction(){
qDebug()<<"AfterConstruction";
}
virtual void doBeforeDestruction(){
qDebug()<<"BeforeDestruction";
}
private:
friend class IBase;
};
int main(int argc, char *argv[])
{
//QObject *obj=new TSubclass() //Compile time error! Nice!
QObject *obj=IBase::create<TSubclass>();
delete obj;//Wrong! BeforeDestruction is NEVER shown!!! <---- How to change this behaviour?
IBase * obj2=IBase::create<TSubclass>();
//delete obj2; //Compile time error! Nice!
obj2->destroy(); //Nice!
}
EDIT:
After some comments, I have to add to the question that I want to do several operations before the destructor for two reasons:
Virtual calls: The virtual calls are not allowed inside the destructor, since they will not call the overriden functions, but only the functions in the current destroying class.
Dynamic casts downcasting: Some of the things to do involve donwcasting via dynamic_cast. dynamic_cast downcasting inside the destructors always fails.
EDIT 2:
The answer of Ezee works as I needed. Here is my complete code snippet, showing the code, with also a dynamic_cast:
template <typename T>
class TAfterConstructionBeforeDestruction: public T {
public:
~TAfterConstructionBeforeDestruction() {
this->beforeDestruction();
}
protected:
using T::T;
};
class IBase: public QObject {
public:
//Now it can be public, just as the one in QObject!
virtual ~IBase(){}
template<typename T>
static IBase * create() {
//Create a
IBase * obj=new TAfterConstructionBeforeDestruction<T>;
obj->afterConstruction();
return obj;
}
protected:
IBase(){}
virtual void afterConstruction(){}
virtual void beforeDestruction(){}
};
class TSubclass: public IBase {
public:
virtual ~TSubclass(){}
protected:
TSubclass(){}
virtual void afterConstruction(){
qDebug()<<"AfterConstruction";
}
virtual void beforeDestruction();
private:
friend class IBase;
};
class TSubclass2: public TSubclass {
public:
virtual ~TSubclass2(){}
protected:
TSubclass2(){}
virtual void beforeDestruction(){
qDebug()<<"BeforeDestruction from Subclass2";
TSubclass::beforeDestruction();
}
};
void TSubclass::beforeDestruction() {
qDebug()<<"BeforeDestruction";
TSubclass2 * sub=dynamic_cast<TSubclass2*>(this);
if (sub) {
qDebug()<<"We are actually a TSubclass2!";
}
}
int main(int argc, char *argv[])
{
//QObject *obj=new TSubclass() //Compile time error! Nice!
QObject *obj=IBase::create<TSubclass>();
delete obj;//Now it works fine!
IBase * obj2=IBase::create<TSubclass2>();
delete obj2; //It is still succeeding to dynamic_cast to TSubclass2 without any problem!
}
First of all, I must say that calling virtual methods from a constructor or a destructor is a very bad practice.
Call doAfterConstruction() from the constructor of the mose derived descendant of IBase.
Call doBeforeDestruction() from the destructor of the mose derived descendant of IBase.
You can do the same using signals/slots:
Declare a signal beforeDestroyed() in IBase (add Q_OBJECT macro also).
In the constructor of IBase connect this signal to a slot doBeforeDestruction (make it a slot).
In the destructor of the mose derived descendant of IBase emit the signal: emit beforeDestroyed().
If you have a lot of descendants you may want to avoid doing the same thing in every constructor/destructor. In this case you can use a template also:
template <class T>
class FirstAndLastCall : public T
{
public:
FirstAndLastCall ()
{
doAfterConstruction();
}
~FirstAndLastCall
{
doBeforeDestruction();
}
}
Usage:
IBase* obj2 = new FirstAndLastCall<TSubclass>();

Why might my virtual function call be failing?

Update: This issue is caused by bad memory usage, see solution at the bottom.
Here's some semi-pseudo code:
class ClassA
{
public:
virtual void VirtualFunction();
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::VirtualFunction()
{
// Intentionally empty (code smell?).
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The C# equivalent is as follows: Removed C# example, as it's not relevant to the actual problem.
Why isn't the ClassB::VirtualFunction function being called when called from ClassA::SomeFunction? Instead ClassA::VirtualFunction is being called...
When I force implementation of the virtual function ClassA::VirtualFunction, like so:
class ClassA
{
public:
virtual void VirtualFunction() = 0;
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The following error occurs at runtime, despite the derrived function deffinately being declared and defined.
pure virtual method called
terminate called without an active exception
Note: It seems like the error can be caused even by bad memory usage. See self-answer for details.
Update 1 - 4:
Comments removed (not releavnt).
Solution:
Posted as an answer.
class Base {
public:
virtual void f() { std::cout << "Base" << std::endl; }
void call() { f(); }
};
class Derived : public Base {
public:
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.call(); // prints Derived
}
If in the Base class you do not want to implement the function you must declare so:
class Base {
public:
virtual void f() = 0; // pure virtual method
void call() { f(); }
};
And the compiler won't allow you to instantiate the class:
int main() {
//Base b; // error b has a pure virtual method
Derived d; // derive provides the implementation: ok
Base & b=d; // ok, the object is Derived, the reference is Base
b.call();
}
As a side note, be careful not to call virtual functions from constructors or destructors as you might get unexpected results.
If you're getting that 'pure virtual method called
terminate called without an active exception' error message, that means you're calling the virtual function from the constructor or destructor of classA (the base class), which you should not do.
on the pure virtual method called error:
You should create a different question as it is in fact different than the other. The answer to this question is on the very last paragraph of my previous answer to your initial question:
Do not call virtual functions from constructors or destructors
class Base
{
public:
Base() { f(); }
virtual void f() = 0;
};
class Derived : public Base
{
public:
virtual void f() {}
};
int main()
{
Derived d; // crashes with pure virtual method called
}
The problem in the code above is that the compiler will allow you to instantiate an object of type Derived (as it is not abstract: all virtual methods are implemented). The construction of a class starts with the construction of all the bases, in this case Base. The compiler will generate the virtual method table for type Base, where the entry for f() is 0 (not implemented in base). The compiler will execute the code in the constructor then. After the Base part has completely been constructed, construction of the Derived element part starts. The compiler will change the virtual table so that the entry for f() points to Derived::f().
If you try calling the method f() while still constructing Base, the entry in the virtual method table is still null and the application crashes.
When A calls VirtualFunction() it will automatically call the version on B. That is the point of virtual functions.
I am not as familiar with the C++ syntax tho. Do you have to declare the function to be virtual at the point of the body as well as in the header?
Alsop, in class B you probably need to mark it as override
in C# its easy. I just don't know the c++ syntax.
public class ClassA
{
public **virtual** void VirtualFunction(){}
public void FooBar()
{
// Will call ClassB.VirtualFunction()
VirtualFunction();
}
}
public class ClassB
{
public **overide** void VirtualFunction()
{
// hello world
}
}
If you want to force the derived classes to implement the VirtualFunction:
class ClassA
{
public:
virtual void VirtualFunction()=0;
void SomeFunction();
}
This is C++. Default the derived function will be called.
If you want to call the base-class function do:
void ClassA::SomeFunction()
{
// ... various lines of code ...
ClassA::VirtualFunction();
}
There's nothing wrong with your code but your sample is incomplete. You do not state where you are calling SomeFunction from.
As has already been pointed out by dribeas you must be careful calling virtual functions from your constructor as the virtual tables are only built up as each class in the hierarchy completes construction.
Edit: The following paragraph of my reply was incorrect. Apologies. It is fine to call SomeFunction from the constructor of ClassB as the vtable is in place (at least) by the end of the initialiser list i.e. once you are in the body of the constructor. It is not fine to call it from ClassA's constructor of course.
Original paragraph:
I suspect you must be calling SomeFunction from the constructor of ClassB at which point only the vtable up to type ClassA will be complete i.e. to the virtual dispatch mechanism your class is still of type ClassA. It only becomes an object of type ClassB when the constructor completes.
To call a virutal function function you need to call via a pointer or a reference.
void ClassA::SomeFunction()
{
VirtualFunction(); // Call ClassA::VirtualFunction
this->VirtualFunction(); // Call Via the virtual dispatch mechanism
// So in this case call ClassB::VirtualFunction
}
You need to be able to distinguish the two different types of call otherwise the classA::VirtualFunction() becomes inaccessible when it is overridden.
As pointed out by others if you want to make the base class version abstract then use the = 0 rather than {}
class A
{
virtual void VirtualFunction() =0;
....
But sometimes it is legitimate to have an empty definition. This will depend on your exact usage.
You aren't defining the function in ClassB correctly, it should be:
public class ClassB
{
public void override AbstractFunction()
{
// hello world
}
}
Then, any call from the base class to virtual/abstract methods will call the implementation on the derived instance.