Make a function a member only if it needs direct access to the representation of a class
Reason
Less coupling than with member functions, fewer functions that can cause trouble by modifying object state, reduces the number of functions that need to be modified after a change in representation.
Example
class Date {
// ... relatively small interface ...
};
// helper functions:
Date next_weekday(Date);
bool operator==(Date, Date);
The "helper functions" have no need for direct access to the representation of a Date.
Note
This rule becomes even better if C++ gets "uniform function call".
Exception
The language requires virtual functions to be members, and not all virtual functions directly access data. In particular, members of an abstract class rarely do.
Note multi-methods.
Exception
The language requires operators =, (), [], and -> to be members.
Exception
An overload set could have some members that do not directly access private data:
class Foobar {
public:
void foo(long x) { /* manipulate private data */ }
void foo(double x) { foo(std::lround(x)); }
// ...
private:
// ...
};
Exception
Similarly, a set of functions could be designed to be used in a chain:
x.scale(0.5).rotate(45).set_color(Color::red);
Typically, some but not all of such functions directly access private data.
Enforcement
The snag is that many member functions that do not need to touch data members directly do.
- Look for non-
virtualmember functions that do not touch data members directly. - Ignore
virtualfunctions. - Ignore functions that are part of an overload set out of which at least one function accesses
privatemembers. - Ignore functions returning
this.