#include <iostream>
using namespace std;
class ClockController {
public:
ClockController() {
cout << "Clock enabled" << endl;
}
~ClockController() {
cout << "Clock disabled" << endl;
}
void write(int offset, int value) {
cout << "Clocked write: " << offset << " " << value << endl;
}
};
class Peripheral {
private:
// Reference ensures the peripheral depends on an existing clock instance
ClockController& m_clock;
public:
// Constructor requires a clock, enforcing the dependency structurally
Peripheral(ClockController& clock) : m_clock(clock) {
cout << "Peripheral ready" << endl;
}
~Peripheral() {
cout << "Peripheral stopped" << endl;
}
void writeReg(int offset, int value) {
// Uses the injected clock dependency
m_clock.write(offset, value);
}
};
class Driver {
private:
/* Order of declaration is critical:
1. Clock is initialized first (Clock enabled)
2. Peripheral is initialized second (Peripheral ready)
*/
ClockController m_clock;
Peripheral m_peripheral;
public:
// Initialize peripheral by passing the already-constructed clock
Driver() : m_clock(), m_peripheral(m_clock) {
cout << "Driver started" << endl;
}
void operate(int offset, int value) {
m_peripheral.writeReg(offset, value);
}
/*
Destruction happens in reverse order:
1. ~Driver() body runs (Driver stopped)
2. m_peripheral is destroyed (Peripheral stopped)
3. m_clock is destroyed (Clock disabled)
*/
~Driver() {
cout << "Driver stopped" << endl;
}
};
int main() {
int offset, value;
if (!(cin >> offset >> value)) return 0;
{
Driver drv;
drv.operate(offset, value);
}
return 0;
}
Input
8 55
Expected Output
Clock enabled Peripheral ready Driver started Clocked write: 8 55 Driver stopped Peripheral stopped Clock disabled