Search code examples
c++functionoverriding

C++ Create a Function that acts like a listener


I don't know what to properly name this but is there a way to create a function on a separate thread that acts as a listener so that other functions can sort of attach to it in a way? Allowing that function to have its code executed in that listener.

void Listener::Run(){
   // create listener here
   // process whatever accesses this
}

then in another file and in a separate namespace/or class, we access this listener function and sort of override it so that we call that exact same function but implement our code so that it executes it asynchronously.

void Listener::Run(){
  //custom code that gets executed on actual listener function
}

Is this possible to do in C++ similar to how its done in Java?


Solution

  • You can very well make some listening function to be run in a separate tread. This is quite common for I/O and network listening. In the context of internal listening between threads, the listening is a little bit less straightforward, and the question too broad for an answer of reasonable length. You could use for example:

    • std::condition_variable in combination with a mutex to have some push-based listening. An alternative is the std::atomic_flag family.
    • periodic std::this_thread::sleep_for in combination with a queue querying at wake-up to have some pull-based mechanism.
    • use some advanced lock-free input queue, to implement some message/signal passing.

    What is not possible to do in a clean way however, is to replace on-the-fly a Listener object by a new object of a Listener-derived class overriding some methods. Some people will say that, yes you could destroy the object an create a new object in the same place, but to make this work is full of ambush and risks of UB.

    The proper alternative to design this, is to run in a separate thread a listener object that uses a strategy pattern, i.e. the actual listening, or processing of the incoming listening is done by another object (the strategy), and you'd then simply replace the strategy. In a multithreaded context, you just make sure that to do the replacement in a harmless way, i.e. not destroying the object that is currently being used in the other thread (typically, you'd use some mutexes for that).

    I'd strongly recommend to read Antony William's book "C++ concurrency in action", which is fully dedicated to multi-threading programming, as multi-threading is quite tricky. Moreover, it may open your eyes to other approaches, that may be more effective than the listener-paradigm.