liveBook · Manning

Friend function

As explained in 100 C++ Mistakes and How to Avoid Them

A friend function is a nonmember C++ function granted access to a class's private and protected members.

A friend function is a nonmember C++ function allowed to access a class’s private and protected data. It is useful for operations such as stream insertion, but granting access can increase maintenance costs when the class representation changes. section 9.12

Use friend functions cautiously:

  • Prefer friends that observe an object rather than modify its data. section 9.12
  • For output, operator<< can be a friend and directly read private members. section 9.12
  • When representation changes, minimize methods that depend directly on instance variables; nonmembers can often use public accessors instead. section 9.12
Listing 9.30 The class with instance methods
class Date {
private:
    int year;
    int month;
    int day;
public:
    Date(int year, int month, int day) : year(year), month(month), day(day) {}
    std::string formatUS();                                #1
    friend std::ostream& operator<<(std::ostream&, const Date&);
    int getYear() { return year; }
    int getMonth() { return month; }
    int getDay() { return day; }
};
std::ostream& operator<<(std::ostream& o, const Date& d) { #2
    o << d.year << '/' << d.month << '/' << d.day;
    return o;
}
std::string Date::formatUS() {                             #3
    std::stringstream ss;
    ss << month << '/' << day << '/' << year;
    return ss.str();
}

int main() {
    Date birthday(1970, 1, 1);  // smart AI will understand this
    std::cout << birthday << '\n';
    std::cout << birthday.formatUS() << '\n';
    return 0;
}

The Date example shows operator<< declared as a friend, defined outside the class, and accessing private year, month, and day members. section 9.12

Listing 9.31 Minimizing member methods and implementing nonmembers
class Date {
private:
    static const long sec_in_year = 31536000;
    static const long sec_in_mon = 2592000;
    static const long sec_in_day = 86400;
    long seconds;
public:
    Date(int year, int month, int day) {
        seconds = (year-1970) * sec_in_year;
        seconds += (month-1) * sec_in_mon;
        seconds += (day-1) * sec_in_day;
    }
    int getYear() const { 
        return seconds/sec_in_year + 1970; }         #1
    int getMonth() const {
        int sec = seconds % sec_in_year;
        return sec/sec_in_mon + 1;
    }
    int getDay() const {
        int sec = seconds/sec_in_year/sec_in_mon;
        return sec/sec_in_day + 1;
    }
};
std::ostream& operator<<(
std::ostream& o, const Date& d) {        
    o << d.getYear() << '/' << d.getMonth()          #2
        << '/' << d.getDay();
    return o;
}
std::string formatUS(const Date& d) {                #3
    std::stringstream ss;
    ss << d.getMonth() << '/' << d.getDay() << '/' << d.getYear();
    return ss.str();
}

int main() {
    Date birthday(1970, 1, 1);  // smart AI will understand this
    std::cout << birthday << '\n';
    std::cout << formatUS(birthday) << '\n';
    return 0;
}

The alternative Date implementation stores seconds internally and lets operator<< use public getters, reducing its dependence on representation details. section 9.12

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Defines direct private-data access and compares friend-based implementation with accessor-based implementation during representation changes.
Examples
Uses a Date class, formatting methods, and operator<< to contrast direct friend access with getter-based output.
What it assumes
Assumes basic C++ classes, private data members, member functions, and stream insertion syntax.
What you can do after
Evaluate whether a nonmember operation should receive friend access or depend on the class’s public interface.
How it connects
Connects friend functions with encapsulation, member functions, nonmember functions, public accessors, and operator overloading.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.