The Queue template class contains three assumptions about the QueueItem template parameter. First, the code:
template <class QueueItem> class Queue { private: QueueItem buffer[100]; ... };assumes that QueueItem has a default constructor (i.e., a constructor that takes no arguments). A default constructor is needed in order to declare and array of a given type. Classes like Location, Shape, and Frame that have default constructors can be used to elaborate the Queue template. However, an error message will result from:
Queue<Message> QueueOfMessages; Queue<Clock> QueueOfClocks;because these classes do not have default constructors. Second, the code:
template <class QueueItem> void Queue<QueueItem>::Insert(QueueItem item) { ... buffer[tail] = item; ... }assumes that the QueueItem class has an appropriately defined assignment operator. All classes have a default assignment operator - a bit-wise copy. In simple classes this is an appropriate assignment operator. For example, in the case of Queue<int> and Queue<Location> the default assignment operator is appropriate. However, the default assignment operator may not be appropriate for a class that contains pointers as private data. Third, the code:
template <class QueueItem> QueueItem Queue<QueueItem>::Remove() { ... return buffer[val]; }returns a copy of the object that is in the internal buffer. This code assumes that an appropriate copy constructor is defined for the class being substituted for QueueItem.
Other templates make more demanding assumptions about the class or type used to instantiate the template. Consider the following template declaration:
template <class T> class Displayable { private: T* displayed; TextBox* textBox; public: Displayable(TextBox* tbox); // testbox to show in void ShowThis(T* d); // what to show void Show(); // show current value void Reset(); // reset displayed from textBox ~Displayable(); };This template is designed to point to a TextBox in which a current value will be displayed and from which a new value can be read. The template also contains a pointer ("displayed") to an object of the template's parameter type. To achieve its intent, the template must make assumptions about how the value can be obtained from the displayed object and how a new value can be given to the displayed object. Since the type of the displayed object is now know (its type is the template's parameter), the template code must make assumptions about (impose constraints on) the type that is used to instantiate the template. The code for the Displayable template is as follows:
template <class T> Displayable<T>::Displayable(TextBox *tbox) {textBox = tbox; displayed = (T*)0;} template <class T> Displayable<T>::ShowThis(T* d) { displayed = d; } template <class T> Displayable<T>::Show() { textBox->SetText(displayed->ToString()); } template <class T> Displayable<T>::Reset() { displayed->FromString(textBox->GetText()); } template <class T> Displayable<T>::~Displayable(){}The Displayable template assumes that the instantiating type has two methods: