How capture derivated this in base class into lambda function?

Viewed 181

I want to code a program that implements a base class and a derivated one of it. I have to execute a thread in the base class that call a pure virtual function implemented into the derivated class.

When I compile and execute the program, the Base::func() is called instead Derivated::func() and my program crash because it cannot execute a pure virtual function. What I have to do to execute the derivated function.

Note : Multiple derivated classes can exist so I can't explicitly use Derivated::func().

class Base {
private:
    std::thread *t = NULL;
    virtual void func() = 0;


public:
    void foo() {
        std::cout << "Base::foo() executed" << std::endl;

        this->t = new std::thread([this]() {
            while (true) {
                func();
            }
        });
    }
};

class Derivated : public Base {
public:
    void func() {
        std::cout << "Derivated::func() executed" << std::endl;
    }
};

int main() {
    Derivated d;
    d.foo();
}

I expect this result :

Base::foo() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
...

But this is appear :

Base::foo() executed
pure virtual method called
terminate called without an active exception
Aborted
2 Answers

While a thread is started, no attempt to join it is made, so the process happily terminate after calling d.foo(); in main.

If you give a getter to the thread, in class Base

std::thread * theThread() { return t; }

in your main:

int main() {
    Derivated d;
    d.foo();

    d.theThread()->join();
}

This way the main thread gets blocked and the other thread is free to go on (and on).

Here is an example that works for me:

#include <iostream>
#include <memory>
#include <thread>

class Base {
private:
    std::unique_ptr<std::thread> t;
    virtual void func() = 0;

public:
    void foo() {
        std::cout << "Base::foo() executed" << std::endl;    
        t = std::make_unique<std::thread>([this]() {
            for (int i=1; i<= 5; i++) {
                this->func();
            }
        });
        t->join();
    }
};

class Derivated : public Base {
public:
    void func() {
        std::cout << "Derivated::func() executed" << std::endl;
    }
};

int main() {
    Derivated d;
    d.foo();

}

Ouput:

Base::foo() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
Derivated::func() executed
Related