145. Fast Buffer Access

#include <iostream>
#include <string>

// Forward declaration lets DisplayDriver know SPIBus exists
class SPIBus;

class DisplayDriver {
public:
    // Defined later, once SPIBus is fully defined
    void fastWrite(SPIBus& bus, int v1, int v2);
};

class SPIBus {
private:
    int buffer[2];

    // This line gives DisplayDriver full access to all private members of SPIBus
    friend class DisplayDriver;

public:
    SPIBus() {
        buffer[0] = 0;
        buffer[1] = 0;
    }

    void dump() {
        std::cout << "Buffer: [ " << buffer[0] << " " << buffer[1] << " ]" << std::endl;
    }
};

// Now that SPIBus is defined, we can implement the method that uses its internals
void DisplayDriver::fastWrite(SPIBus& bus, int v1, int v2) {
    bus.buffer[0] = v1;
    bus.buffer[1] = v2;
}

int main() {
    SPIBus bus;
    DisplayDriver driver;
    int N;
    if (!(std::cin >> N)) return 0;

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

        if (cmd == "WRITE") {
            int v1, v2;
            std::cin >> v1 >> v2;
            driver.fastWrite(bus, v1, v2);
        } else if (cmd == "SHOW") {
            bus.dump();
        }
    }
    return 0;
}

Explanation & Logic Summary:

  • Friend Class: By writing friend class DisplayDriver; inside SPIBus, we tell the compiler that DisplayDriver is "trusted."
  • Access Privilege: Normally, bus.buffer is invisible to the outside world. However, methods inside DisplayDriver can see and modify it just as if they were members of SPIBus.
  • Forward Declaration: We declared class SPIBus; at the top so DisplayDriver could mention it in a function signature (fastWrite) before SPIBus was fully defined. We defined the body of fastWrite at the bottom, after SPIBus was fully defined, so it knew buffer existed.

Firmware Relevance & Real-World Context:

  • Bypassing Abstraction Layers: Layered architectures (HAL -> Driver -> Middleware) are good for safety but slow. Sometimes, the Middleware needs to poke the HAL directly for a time-critical operation (like filling a DMA buffer). friend allows this specific bypass without making the HAL public to everyone.
  • Testing Mocks: A TestRunner class can be a friend of the MotorController to inject fake error states or sensor readings into private variables that are otherwise read-only (hardware inputs).

 

 

 

Loading...

Input

3 SHOW WRITE 55 99 SHOW

Expected Output

Buffer: [ 0 0 ] Buffer: [ 55 99 ]