TITLE: Mode "has-a" or "is-implemented-in-terms-of" through layering (This example from "Effective C++" by Scott Meyers, p142 - 145.) Layering is the process of building one class on top of another class by having the layering class contain an object of the layered class as a data member. For example: class String { ... }; class Address { ... }; class PhoneNumber { ... }; class Person { private: String name; // layered object Address address; // ditto PhoneNumber voiceNumber; // ditto PhoneNumber faxNumber; // ditto public: ... }; In this example, the Person class is said to be layered on top of the String, Address, and PhoneNumber classes, because it contains data members of those types. Layering is also known as containment or embedding. The Person class above demonstrates the has-a relationship. A Person object has a name, an address, and telephone numbers for both voice and FAX communication. You wouldn't say that a person is a string or that a person is an address, you would say that a person has a string ... Somewhat more troublesome is the difference between isa and is-implemented- in-terms-of. For example, suppose that you have a class that implements linked lists of objects ... template class LinkedList { private: ... public: LinkedList (); LinkedList (const LinkedList& rhs); virtual ~LinkedList(); LinkedList& operator=(const LinkedList& rhs); virtual void insert (T& item, int position); virtual T& remove (int position); virtual T& operator[] (int position); virtual const T& operator[] (int position) const; int length () const; }; ... Now suppose that your real goal is to develop a template class to represent sets of items of type T, where a set is, as usual, an unordered collection without duplicates. Being the data structure maven that you are, you know that of the nearly limitless choices for implementing sets, one particularly simple way is to employ linked lists. Because you have a linked list class already written, you decide to engage in a little code reuse by having your nascent Set class inherit from LinkedList. After all, in your implementation, a Set object will in fact be a LinkedList object. Your decision is further buttressed by the fact that the LinkedList class is clearly designed to be a base class: notice the virtual functions, including, significantly, the virtual destructor... Hence you declare your Set class like this: // the wrong way to associate sets and linked lists template class Set : public LinkedList { ... }; Everything may seem fine and dandy at this point, but in fact there is something quite wrong. ...if B isa A, then everything that is true of A is also true of B. However, a LinkedList object is an ordered collection, a fact made plain by the presence of the operator[] functions that take a position argument in the LinkedList class. In contrast, a Set is an unordered collection, and the operator[] functions it inherits from LinkedList make no sense for it. It is not true that a Set isa LinkedList, because some of the things that are true for LinkedList objects are not true for Set objects. Because the relationship between these two classes isn't isa, public inheritance is the wrong way to model that relationship. The right way to model that relationship is to realize that a Set object can be implemented in terms of a LinkedList object...