99. Refactor Driver–Bus Relationship

#include <iostream>
using namespace std;

class Bus {
public:
    Bus() {
        cout << "Bus ready" << endl;
    }

    ~Bus() {
        cout << "Bus stopped" << endl;
    }

    void write(int addr, int val) {
        cout << "Bus write: " << addr << " " << val << endl;
    }
};

class Driver {
private:
    Bus& bus;

public:
    Driver(Bus& b) : bus(b) {
        cout << "Driver started" << endl;
    }

    void operate(int addr, int val) {
        bus.write(addr, val);
    }

    ~Driver() {
        cout << "Driver stopped" << endl;
    }
};

int main() {
    int a1, v1, a2, v2;
    cin >> a1 >> v1 >> a2 >> v2;

    {
        Bus sharedBus;
        Driver d1(sharedBus);
        Driver d2(sharedBus);
        d1.operate(a1, v1);
        d2.operate(a2, v2);
    }

    return 0;
}

Explanation & Logic Summary:
The original design incorrectly modeled drivers as buses using inheritance, resulting in multiple bus instances. This violates real hardware behavior. By switching to composition, the bus becomes a shared resource with a single lifetime, while drivers correctly depend on it. This makes ownership, lifetime, and responsibilities explicit and safe.

Firmware Relevance & Real-World Context:
In real firmware systems, SPI, I²C, and memory buses are single physical resources shared by multiple drivers. Drivers must coordinate access rather than duplicate hardware abstractions. Composition accurately reflects this relationship and prevents flawed HAL designs that cannot scale to real embedded systems.

 

 

 

 

Loading...

Input

10 20 30 40

Expected Output

Bus ready Driver started Driver started Bus write: 10 20 Bus write: 30 40 Driver stopped Driver stopped Bus stopped