152. Class Method Callback

#include <iostream>
#include <functional>
#include <string>

class Driver {
private:
    std::function<void()> callback;
public:
    void setCallback(std::function<void()> cb) {
        callback = cb;
    }
    void execute() {
        if (callback) callback();
    }
};

class Motor {
private:
    int position = 0;
public:
    void step() {
        position++;
        std::cout << "Position: " << position << std::endl;
    }
};

int main() {
    Driver driver;
    Motor motor;

    // We use a lambda to wrap the member function call.
    // [&motor] captures the specific motor instance from the stack.
    // When the driver calls this lambda, the lambda calls motor.step().
    driver.setCallback([&motor]() {
        motor.step();
    });

    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        std::string cmd;
        std::cin >> cmd;
        if (cmd == "TRIG") {
            driver.execute();
        }
    }
    return 0;
}

Explanation & Logic Summary:

  • The Problem: A generic Driver class knows nothing about the Motor class. It just knows how to call a void() function. Furthermore, Motor::step technically has a hidden argument (this), so it doesn't match the signature void().
  • The Solution: The Lambda acts as an Adapter. It matches the void() signature expected by the Driver, but inside its body, it has access to the motor instance (via capture) and calls the specific method.
  • Reference Capture: We use [&motor] because we want to affect the existing motor object. If we captured by value [motor], the lambda would make a copy of the motor, step the copy's position, and the original motor would stay at 0.

Firmware Relevance & Real-World Context:

  • Object-Oriented Drivers: In C++, you might have multiple instances of a class (e.g., Servo motor1; Servo motor2;). You can bind motor1 to Timer1 and motor2 to Timer2 using this exact technique.
  • Event Dispatching: A GUI button press (generic event) can be routed to a specific screen controller's open() method.
  • Dependency Injection: This decouples the low-level driver (which triggers events) from the high-level application logic (which handles them).

 

 

 

Loading...

Input

2 TRIG TRIG

Expected Output

Position: 1 Position: 2