![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 19.6. Специальные реализации шаблона
1: #include < iostream.h> 2: 3: const int DefaultSize = 3; 4: 5: // Обычный класс, из объектов которого создается массив 6: class Animal 7: { 8: public: 9: // конструкторы 10: Animal(int); 11: Animal(); 12: ~Animal(); 13: 14: // методы доступа 15: int GetWeight() const { return itsWeight; } 16: void SetWeight(int theWeight) { itsWeight = theWeight; } 17: 18: // дружественные операторы 19: friend ostream& operator< < (ostream&, const Animal&); 20: 21: private: 22: int itsWeight; 23: }; 24: 25: // оператор вывода обьектов типа Animal 26: ostream& operator< < 27: (ostream& theStream, const Animal& theAnimal) 28: { 29: theStream < < theAnimal.GetWeight(); 30: return theStream; 31: } 32: 33: Animal:: Animal(int weight): 34: itsWeight(weight) 35: { 36: cout < < " animal(int) "; 37: } 38: 39: Animal:: Animal(): 40: itsWeight(0) 41: { 42: cout < < " animal() "; 43: } 44: 45: Animal:: ~Animal() 46: { 47: cout < < " Destroyed an animal..."; 48: } 49: 50: template < class T> // обьявляем шаблон и параметр 51: class Array // параметризованный класс 52: { 53: public: 54: Array(int itsSize = DefaultSize); 55: Array(const Array & rhs); 56: ~Array() { delete [] pType; } 57: 58: // операторы 59: Array& operator=(const Array&); 60: T& operator[](int offSet) { return pType[offSet]; } 61: const T& operator[](int offSet) const 62: { return pType[offSet]; } 62: 63: // методы доступа 64: int GetSize() const { return itsSize; } 65: 66: // функция-друг 67: friend ostream& operator< < (ostream&, const Array< T> &); 68: 69: private: 70: T *pType; 71: int itsSize; 72: }; 73: 74: template < class T> 75: Array< T>:: Array(int size = DefaultSize): 76: itsSize(size) 77: { 78: pType = new T[size]; 79: for (int i = 0; i< size; i++) 80: pType[i] = (T)0; 81: } 82: 83: template < class T> 84: Array< T> & Array< T>:: operator=(const Array & rhs) 85: { 86: if (this == & rhs) 87: return *this; 88: delete [] pType; 89: itsSize = rhs.GetSize(); 90: pType = new T[itsSize]; 91: for (int i = 0; i< itsSize; i++) 92: pType[i] = rhs[i]; 93: return *this; 94: } 95: template < class T> 96: Array< T>:: Array(const Array & rhs) 97: { 98: itsSize = rhs.GetSize(); 99: pType = new T[itsSize]; 100: for (int i = 0; i< itsSize; i++) 101: pType[i] = rhs[i]; 102: } 103: 104: 105: template < olass T> 106: ostream& operator< < (ostream& output, const Array< T> & theArray) 107: { 108: for (int i = 0; i< theArray.GetSize(); i++) 109; output < < " [" < < i < < " ] " < < theArray[i] < < endl; 110: return output; 111: } 112: 113: 114: Array< Animal>:: Array(int AnimalArraySize): 115: itsSize(AnimalArraySize) 116: { 117: pType = new Animal[AnimalArraySize]; 118: } 119: 120: 121: void IntFillFunction(Array< int> & theArray); 122: void AnimalFillFunction(Array< Animal> & theArray); 123: 124: int main() 125: { 126: Array< int> intArray; 127: Array< Animal> animalArray; 128: IntFillFunction(intArray); 129: AnimalFillFunction(animalArray); 130: cout < < " intArray...\n" < < intArray; 131: cout < < " \nanimaiArray...\n" < < animalArray < < endl; 132: return 0; 133: } 134: 135: void IntFillFunction(Array< int> & theArray) 136: { 137: bool Stop = false; 138: int offset, value; 139: while (! Stop) 140: { 141: cout < < " Enter an offset (0-9) and a value, "; 142: cout < < " (-1 to stop): "; 143: cin > > offset > > value; 144: if (offset < 0) 145: break; 146: if (offset > 9) 147: { 148: cout < < " ***Please use values between 0 and 9.***\n"; 149: continue; 150: } 151: theArray[offset] = value; 152: } 153: } 154: 155: 156: void AnimalFillFunction(Array< Animal> & theArr, 157: { 158: Animal * pAnimal; 159: for (int i = 0; i< theArray.GetSize(); i++) 160: { 161: pAnimal = new Animal(i*10); 162: theArray[i] = *pAnimal; 163: delete pAnimal; 164: } 165: }
Примечание: Для облегчения анализа в приведенные ниже результаты работы программы добавлены номера строк, но в действительности они не выводятся.
Результат: 1: animal() animal() animal() Enter an offset (0-9) and a value. (-1 to stop): 0 0 2: Enter an offset (0-9) and a value. (-1 to stop): 1 1 3: Enter an offset (0-9) and a value. (-1 to stop): 2 2 4: Enter an offset (0-9) and a value. (-1 to stop): 3 3 5: Enter an offset (0-9) and a value. (-1 to stop): -1 -1 6: animal(int) Destroyed an animal...animal(int) Destroyed an animal...animal(int) Destroyed an animal...initArray... 7: [0] 0 8: [1] 1 9: [2] 2 10: 11: animal array 12: [0] 0 13: [1] 10 14: [2] 20 15: 16: Destroyed an animal...Destroyed an animal...Destroyed an animal 17: < < < Second run > > > 18: animal(int) Destroyed an animal.. 19: animal(int) Destroyed an animal.. 20: animal(int) Destroyed an animal.. 21: Enter an offset (0-9) and a value. (-1 to stop): 0 0 22: Enter an offset (0-9) and a value. (-1 to stop): 1 1 23: Enter an offset (0-9) and a value. (-1 to stop): 2 2 24: Enter an offset (0-9) and a value. (-1 to stop): 3 3 25: animal(int) 26: Destroyed an animal... 27: animal(int) 28: Destroyed an animal... 29: animal(int) 30: Destroyed an animal... 31: initArray... 32: [0] 0 33: [1] 1 34: [2] 2 35: 36: animal array 37: [0] 0 38: [1] 10 39: [2] 20 40: 41: Destroyed an animal... 42: Destroyed an animal... 43: Destroyed an animal...
Анализ: В листинге 19.6 оба класса воспроизведены во всей своей полноте, чтобы лучше наблюдать за созданием и удалением временных объектов Animal. Для упрощения результатов работы значение DefaultSize было уменьшено до 3. Все конструкторы и деструкторы класса Animal (строки 33—48) выводят на экран сообщения, сигнализирующие об их вызове. В строках 74-81 объявляется конструктор класса Array. В строках 114-118 показан специализированный конструктор Array для массива объектов типа Animal. Обратите внимание, что в этом специализированном конструкторе не делается никаких явных присвоений и исходные значения для каждого объекта Animal устанавливаются стандартным конструктором. При первом выполнении этой программы на экран выводится ряд сообщений. В строке 1 результатов выполнения программы зафиксированы сообщения трех стандартных конструкторов, вызванных при создании массива. Затем пользователь вводит четыре числа, которые помещаются в массив целых чисел. После этого управление передается функции AnimalFillFunction(). Здесь в области динамического обмена создается временный объект Animal (строка 161), а его значение используется для модификации объекта Animal в массиве (строка 162). В следующей же строке (с номером 163) временный объект Animal удаляется. Этот процесс повторяется для каждого члена массива и отражен в строке 6 результатов выполнения программы. В конце программы созданные массивы удаляются, а при вызове их деструкторов также удаляются и все их объекты. Процесс удаления отражен в строке 16 результатов выполнения программы. При следующем выполнении программы (результаты показаны в строках 18-43) были закомментированы несколько строк программного кода (со 114 по 118), содержащие специализированный конструктор класса Array. В результате при выполнении программы для создания массива объектов Animal вызывается конструктор шаблона, показанныйвстроках74-81. Это приводит к созданию временных объектов Animal для каждого члена массива (строки программы 79 и 80), что отражается в строках 18-20 результатов выполнения программы. Во всех остальных аспектах, результаты выполнения двух вариантов программы, как и следовало ожидать, идентичны.
|