Я написал этот простой пример, чтобы получить Что происходит я хочу, чтобы все логики должны быть реализованы в базовом классе и получены конкретные методы в производном классе, так:C++ называть
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class base
{
public:
base() : stop(false) {}
virtual ~base()
{
std::cout << "Destructor base\n";
if(handle.joinable())
{
stop = true;
handle.join();
}
}
void runThread() { handle = std::thread(worker, this); }
virtual void stopThread() { std::cout << "Base stopThread\n"; }
protected:
std::atomic<bool> stop;
std::thread handle;
static void worker(base *me)
{
while(me->stop == false)
{
std::cout << "Working\n";
me->stopThread(); // this one in called as derived
std::this_thread::sleep_for(std::chrono::seconds(1));
}
me->stopThread(); // this one is called as base
}
};
class derived : public base
{
public:
~derived()
{
std::cout << "Destructor derived\n";
}
private:
void stopThread() { std::cout << "derived stopThread\n"; }
};
int main()
{
derived der;
der.runThread();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
и Результат:
Working
derived stopThread
Working
derived stopThread
Working
derived stopThread
Destructor derived
Destructor base
Base stopThread <-- hmmm
Итак, все работает отлично, кроме базового деструктора - он вызывает базу :: stopThread. Почему это происходит? Если я сделаю это виртуальным, я получу исключение.
Я могу исправить это, переместив деструктор в производный класс, но это не ясно, потому что я хочу, чтобы вся логика была реализована в базовом классе.
Где я ошибаюсь?
Благодаря
Ничего общего с потоками: динамический тип объекта внутри его деструктора является его статическим типом, поскольку любая производная часть уже уничтожена. – Quentin
Кстати, факт, что чистая виртуальная функция дал вам исключение, должен был намекнуть вам. – SergeyA
Как примечание, правила меняются в зависимости от языков, поэтому вам нужно изучить правила для своего языка, если хотите сделать некоторые продвинутые вещи. – Phil1970