144. Hardware Monitor

#include <iostream>
#include <string>

class TemperatureSensor {
private:
    int raw_adc_value;

    // Grants access to private members for this specific function
    friend void debugMonitor(const TemperatureSensor& s);

public:
    TemperatureSensor() : raw_adc_value(0) {}

    void update(int val) {
        raw_adc_value = val;
    }
};

// This is a standalone global function, NOT a member of TemperatureSensor
void debugMonitor(const TemperatureSensor& s) {
    // We can access 'raw_adc_value' directly because we are a friend
    std::cout << "Debug: Raw ADC = " << s.raw_adc_value << std::endl;
}

int main() {
    TemperatureSensor sensor;
    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        std::string cmd;
        std::cin >> cmd;

        if (cmd == "READ") {
            int val;
            std::cin >> val;
            sensor.update(val);
        } else if (cmd == "DEBUG") {
            debugMonitor(sensor);
        }
    }
    return 0;
}

Explanation & Logic Summary:

  • Encapsulation Violation (Controlled): Normally, accessing s.raw_adc_value from outside the class triggers a compiler error "member is private". The friend declaration inside the class gives debugMonitor specific permission to bypass this.
  • Use Case: This is superior to adding a public getRawADC() method because we don't want normal application code (like the UI or control logic) to depend on raw values. Only the specific debug tool should see them.

Firmware Relevance & Real-World Context:

  • ISRs: An Interrupt Service Routine (ISR) is often a plain C function. It may need to update a private flag inside a C++ object. Making the ISR a friend allows this without exposing the flag publicly.
  • Unit Testing: Test frameworks often use friend to inspect private internal states during testing (white-box testing) without breaking encapsulation for production code.

 

 

 

Loading...

Input

3 READ 1024 DEBUG READ 2048

Expected Output

Debug: Raw ADC = 1024