While designing an interface for a class I normally get caught in two minds whether should I provide member functions which can be calculated / derived by using combinations of other member functions. For example:
class DocContainer { public: Doc* getDoc(int index) const; bool isDocSelected(Doc*) const; int getDocCount() const; //Should this method be here??? //This method returns the selected documents in the contrainer (in selectedDocs_out) void getSelectedDocs(std::vector<Doc*>& selectedDocs_out) const; };
Should I provide this as a class member function or probably a namespace where I can define this method? Which one is preferred?
In general, you should probably prefer free functions. Think about it from an OOP perspective.
If the function does not need access to any private members, then why should it be given access to them? That’s not good for encapsulation. It means more code that may potentially fail when the internals of the class is modified.
It also limits the possible amount of code reuse.
If you wrote the function as something like this:
Then the same implementation of getSelectedDocs will work for any class that exposes the required functions, not just your DocContainer.
Of course, if you don’t like templates, an interface could be used, and then it’d still work for any class that implemented this interface.
On the other hand, if it is a member function, then it’ll only work for this particular class (and possibly derived classes).
The C++ standard library follows the same approach. Consider
std::find, for example, which is made a free function for this precise reason. It doesn’t need to know the internals of the class it’s searching in. It just needs some implementation that fulfills its requirements. Which means that the samefind()implementation can work on any container, in the standard library or elsewhere.Scott Meyers argues for the same thing.
If you don’t like it cluttering up your main namespace, you can of course put it into a separate namespace with functionality for this particular class.