Skip to main content

Item 23: Prefer non-member non-friend functions to member functions

Concept

Encapsulation is inversely related to the number of functions that can access private data. A non-member non-friend function provides greater encapsulation than a member function because it doesn't increase the number of functions that can access the class's private parts. The natural way to organize such convenience functions is to put them in the same namespace as the class, possibly spread across multiple header files (like the STL does with <vector>, <algorithm>, etc.).

Code Example

class WebBrowser {
public:
void clearCache();
void clearHistory();
void removeCookies();
// ...
};

// BAD as a member: increases the number of functions with access to privates
// class WebBrowser {
// void clearEverything(); // calls clearCache, clearHistory, removeCookies
// };

// GOOD: non-member non-friend in the same namespace
namespace WebBrowserStuff {

class WebBrowser { /* ... */ };

// Convenience function — same namespace, not a member or friend
void clearBrowser(WebBrowser& wb) {
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}

} // namespace WebBrowserStuff

// Can be split across headers for modularity:
// "webbrowser.h" — class WebBrowser core
// "webbrowsercache.h" — cache-related convenience functions
// "webbrowsercookies.h" — cookie-related convenience functions

Full source code

Things to Remember

  • Prefer non-member non-friend functions to member functions. Doing so increases encapsulation, packaging flexibility, and functional extensibility.
  • This reasoning applies only to non-friend functions. A friend function has the same access as a member function from an encapsulation standpoint.
  • Item 22 — Declare data members private (encapsulation fundamentals)
  • Item 24 — Non-member functions and type conversions