TITLE: nice and regular functions [ This is follow on discussion to a thread which began stating that every class should have a copy constructor, virtual destructor, and assignment operator defined. See the tip "big3". -adc ] RESPONSE: ellis@allegra.att.com (Margaret Ellis), 11/28/95 In a follow-up letter to the editor, we conclude that there is *no* member function that should be provided by every class. RESPONSE: Dick.Menninger@DaytonOH.ATTGIS.COM (mennid) I guess it is an interesting abstract result that there are enough odd-ball cases that, taken together, manage to eliminate all member functions. What would be more helpful, and, I suspect more in the spirit (rather than literal interpretation) of such statements would be clear exposition of major subsets of cases that have characteristic sets of member functions for good implementations. Similarly, looking at member functions, what are good rules of thumb for determining that they are good or bad choices to provide. These two could be seen as the implementation side of patterns. RESPONSE: ellis@allegra.att.com (Margaret Ellis), 5 Dec 95 Martin Carroll and I discuss two kinds of functions along these lines: - the regular functions - the nice functions The regular functions are: - the copy constructor - the destructor - the principal assignment operator - the equality and inequality operators In a well designed class, the regular functions (if they are provided) implement regular semantics (the semantics you would expect). The semantics of the regular functions are: - T::T(const T& t); Construct a T whose (abstract) value is the same as T. - T::~T(); Destroy this T. - const T& T::operator=(constT& t); Set the value of this object to the (abstract) value of t and return a reference to this object. [ The const on the return type of operator== is a mistake. -adc ] - bool operator==(const T& t1, const T& t2); Return true if and only if t1 and t2 have the same abstract value. - bool operator!=(const T& t1, const T& t2); Return true if and only if t1 and t2 have different values. The nice functions are: - the default constructor - the copy constructor - the destructor - the assignment operator - the equality operator It can be shown (see "Designing and Coding Reusable C++", by Carroll and Ellis, Addison-Wesley, 1995) that a class that does not provide the nice functions limits, sometimes severely, what users can do with it. Thus, whenever possible, classes should provide the nice functions. And there are more issues about what functions groups of classes should provide. Consider a library of collection classes. Clearly, a list class and a set class, for example, have to provide some function for inserting objects into a list or set respectively. For consistency and ease of use of the library, we'll want to give our insertion functions the same name, say "insert". Now suppose we also provide a stack class. Should its insertion function be called "insert" for consistency with our other collection classes or "pop" for consistency with the way users think about stacks? Carroll and I discuss consistency of interfaces, as well as other interface issues (What conversions should be provided? How should const be used? Do shallow and deep copy functions make sense?) in our book.