C ++ Inheritance: calling a virtual method when it was overridden

I am trying to create a service object that can be started (i.e. execute its run() ) in a separate thread. This is a service object.

 #include <boost/noncopyable.hpp> #include <atomic> #include <thread> #include <iostream> class service : public boost::noncopyable { public: service() : stop_(false), started_(false) { } virtual ~service() { stop(); if (thread_.joinable()) { thread_.join(); } } virtual void stop() { stop_ = true; } virtual void start() { if (started_.load() == false) { started_ = true; thread_ = std::thread([&] () { run(); }); } } protected: virtual void run() = 0; std::atomic<bool> stop_; std::atomic<bool> started_; std::thread thread_; }; 

I create a test class that inherits from this abstract class and is called in the main() function

 class test : public service { public: test() : service() { std::cout<< "CTOR" << std::endl; start(); } ~test() { std::cout<< "DTOR" << std::endl; } protected: void run() override { std::cout << "HELLO WORLD" <<std::endl; } }; int main() { test test1; return 0; } 

Now that I am doing this, why am I getting a pure virtual function called error message? The run() function is explicitly overridden in the test class. What's worse, does it work correctly sometimes?

 $ ./a.out CTOR DTOR pure virtual method called terminate called without an active exception $ ./a.out CTOR DTOR pure virtual method called terminate called without an active exception $ ./a.out CTOR DTOR pure virtual method called terminate called without an active exception $ ./a.out CTOR DTOR HELLO WORLD $ ./a.out CTOR DTOR pure virtual method called terminate called without an active exception 

What could be wrong here?

+7
c ++ inheritance multithreading virtual-functions
source share
1 answer

Follow step by step:

1) You create an object.

2) You will run the following code snippet:

 if (started_.load() == false) { started_ = true; thread_ = std::thread([&] () { run(); }); } 

The parent thread immediately returns to main() , where it exits immediately and destroys your object.

Here is your mistake:

  • You are not guaranteed that the thread running in start() will reach the run() call, above, before the parent thread terminates the process. Both the child thread and the parent thread work simultaneously.

So, each time, the parent thread destroys the object before the child thread hits the mechanism, and calls run ().

At this point, the object whose run () method is being called is already destroyed.

Undefined.

The statement you click from time to time is one possible outcome of this undefined behavior.

+10
source share

All Articles