146. Stream Operator Overloading

#include <iostream>
#include <string>

class SystemStatus {
private:
    int code;
    std::string message;

    // Friend declaration allows the global operator<< function to access private members
    friend std::ostream& operator<<(std::ostream& os, const SystemStatus& s);

public:
    SystemStatus(int c, std::string m) : code(c), message(m) {}
};

// Global function definition
std::ostream& operator<<(std::ostream& os, const SystemStatus& s) {
    os << "[Status: " << s.code << "] " << s.message;
    return os; // Return the stream to allow chaining (e.g., cout << obj << endl)
}

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

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

        SystemStatus status(code, msg);
        std::cout << status << std::endl;
    }
    return 0;
}

Explanation & Logic Summary:

  • Why Friend? The syntax cout << obj means we are calling a function operator<<(cout, obj). The first argument is ostream, which we cannot modify (it's a system class). Thus, we must write a global function. To let this global function print private data (code, message), we make it a friend.
  • Return Value: We return std::ostream& (the same stream we received) to support chaining. This is what allows cout << obj << endl; to work—the first << returns cout, which is then used by the second <<.

Firmware Relevance & Real-World Context:

  • Logging: Instead of writing Log(sensor.getVal(), sensor.getID()), you can simply write Log << sensor;. This makes debug code cleaner and less error-prone.
  • Serial Output: You can overload << for a UARTStream class, allowing you to send complex objects over serial ports naturally: uart << packet;.

 

 

 

 

Loading...

Input

2 404 NotFound 200 OK

Expected Output

[Status: 404] NotFound [Status: 200] OK