- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Освой самостоятельно за 21 день - Джесс Либерти
Шрифт:
Интервал:
Закладка:
Раздел закрытых данных содержит переменные-члены размера массива и указатель на массив объектов, реально помещенных в память.
Функции шаблона
Если вы хотите передать функции объект массива, нужно передавать конкретный экземпляр массива, а не шаблон. Поэтому, если некоторая функция SomeFunction() принимает в качестве параметра целочисленный массив, используйте следующую запись:
void SomeFunction(Array<int>&); // правильно
А запись
void SomeFunction(Array<T>&); // ошибка!
неверна, поскольку отсюда не ясно, что представляет собой выражение T&. Запись
void SomeFunction(Array &); // ошибка!
тоже ошибочна, так как объекта класса Array не существует — есть только шаблон и его экземпляры.
Чтобы реализовать более общий подход использования объектов, созданных на основе шаблона, нужно объявить функцию шаблона:
template <class T>
void MyTemplateFunction(Array<T>&); // верно
Здесь MyTemplateFunction() объявлена как функция шаблона, на что указывает первая строка объявления. Заметьте, что функции шаблонов, подобно другим функциям, могут иметь любые имена.
Функции шаблонов, помимо объектов, заданных в параметризованной форме, могут также принимать и экземпляры шаблона. Проиллюстрируем это на примере:
template <class T>
void MyOtherFunction(Array<T>&, Array<int>&); // верно
Обратите внимание на то, что эта функция принимает два массива: параметризованный массив и массив целых чисел. Первый может быть массивом любых объектов, а второй — только массивом целых чисел.
Шаблоны и друзья
В шаблонах классов могут быть объявлены три типа друзей:
• дружественный класс или функция, не являющиеся шаблоном;
• дружественный шаблон класса или функция, входящая в шаблон;
• дружественный шаблон класса или шаблонная функция, специализированные по типу данных.
Дружественные классы и функции, не являющиеся шаблонами
Можно объявить любой класс или функцию, которые будут дружественны по отношению к вашему классу шаблона. В этом случае каждый экземпляр класса: будет обращаться с другом так, как будто объявление класса-друга было сделано в этом конкретном экземпляре. В листинге 19.3 в определении шаблона класса Array добавлена тривиальная дружественная функция Intrude(), а в управляющей.программе делается вызов этой функции. В качестве друга функция Intrude() получает доступ к закрытым данным класса Array. Но поскольку эта функция не является функцией шаблона, то ее можно вызывать только для массива заданного типа (в нашем примере для массива целых чисел).
Листинг 18.3. Функция-друг, не являющаяся шаблоном
1: // Листинг 19.3. Использование в шаблонах функций-друзей определенного типа
2:
3: #include <iostream.h>
4:
5: const int DefaultSize = 10;
6:
7: // обьявляем простой класс Animal, чтобы можно
8: // было создать массив животных
9:
10: class Animal
11: {
12: public:
13: Animal(int);
14: Animal();
15: ~Animal() { }
16: int GetWeight() const { return itsWeight; }
17: void Display() const { cout << itsWeight; >
18: private:
19: int itsWeight;
20: };
21:
22: Animal::Animal(intweight):
23: itsWeight(weight)
24: { }
25:
26: Animal::Animal():
27: itsWeight(0)
28: { }
29:
30: template <class T> // обьявляем шаблон и параметр
31: class Array // параметризованный класс
32: {
33: public:
34: // конструкторы
35: Array(int itsSize = DefaultSize);
36: Array(const Array &rhs);
37: ~Array() { delete [] pType; }
38:
39: // операторы
40: Array& operator=(const Array&);
41; T& operator[](int offSet) { return pType[offSet]; }
42: const T& operator[](int offSet) const
43: { return pType[offSet]; }
44: // методы доступа
45: int GetSize() const { return itsSize; }
46:
47: // функция-друг
48: friend void Intrude(Array<int>);
49
50: private:
51: T *рТуре;
52: int itsSize;
53: };
54:
55: // Поскольку функция-друг не является шаблоном, ее можно использовать только
56: // с массивами целых чисел! Но она получает доступ к закрытым данным класса.
57: void Intrude(Array<int> theArray)
58: {
59: cout << "n*** Intrude ***n";
60: for (int i = 0; i < theArray.itsSize; i++)
61: cout << "i: " << theArray.pType[i] << endl;
62: cout << "n"
63: }
64:
65: // Ряд выполнений...
66:
67: // выполнение конструктора
68: template <class T>
69: Array<T>::Array(int size):
70: itsSize(size)
71: {
72: pType = new T[size];
73: for (int i = 0; i<size; i++)
74: pType[i] = 0;
75: }
76:
77: // конструктор-копировщик
78: template <class T>
79: Array<T>::Array(const Array &rhs)
80: {
81: itsSize = rhs.GetSize();
82: pType = new T[itsSize];
83: for (int i = 0; i<itsSize; i++)
84: pType[i] = rhs[i];
85: }
86:
87: // перегрузка оператора присваивания (=)
88: template <class T>
89: Array<T>& Array<T>::operator=(const Array &rhs)
90: {
91: if (this == &rhs)
92: return *this;
93: delete [] pType;
94: itsSize = rhs.GetSize();
95: pType = new T[itsSize];
96: for (int i = 0; i<itsSize; i++)
97: pType[i] = rhs[i];
98: return *this;
99: }
100:
101: // управляющая программа
102: int main()
103: {
104: Array<int> theArray; // массив целых
105: Array<Animal> theZoo; // массив животных
106: Animal *pAnimal;
107:
108: // заполняем массивы
109: for (int i = 0; i < theArray.GetSize(); i++)
110: {
111: theArray[i] = i*2;
112: pAnimal = new Animal(i*3);
113: theZoo[i] = *pAnimal;
114: }
115:
116: int j;
117: for (j = 0; j < theArray.GetSize(); j++)
118: {
119: cout << "theZoo[" << j << "]:t";
120: theZoo[j].Display();
121: cout << endl;
122: }
123: cout << "Now use the friend function to";
124: cout << "find the members of Array<int>";
125: Intrude(theArray);
126:
127: cout << "nnDone.n";
128: return 0;
129: }
Результат:
theZoo[0]: 0
theZoo[1]: 3
theZoo[2]: 6
theZoo[3]: 9
theZoo[4]: 12
theZoo[5]: 15
theZoo[6]: 18
theZoo[7]: 21
theZoo[8]: 24
theZoo[9]: 27
Now use the friend function to find the members of Array<int>
*** Intrude ***
i: 0
i: 2
i: 4
i: 6
i: 8
i: 10
i: 12
i: 14
i: 16
i: 18
Done.
Анализ: Объявление шаблона Array было расширено за счет включения дружественной функции Intrude(). Это объявление означает, что каждый экземпляр массива типа int будет считать функцию Intrude() дружественной, а следовательно, она будет иметь доступ к закрытым переменным-членам и функциям-членам экземпляра этого массива.
В строке 60 функция lntrude() непосредственно обращается к члену itsSize, а в строке 61 получает прямой доступ к переменной-члену pType. В данном случае без использования функции-друга можно было бы обойтись, поскольку класс Array предоставляет открытые методы доступа к этим данным. Этот листинг служит лишь примером того, как можно объявлять и использовать функции-друзья шаблонов.
Дружественный класс или функция как общий шаблон
В класс Array было бы весьма полезно добавить оператор вывода данных. Это можно сделать путем объявления оператора вывода для каждого возможного типа массива, но такой подход свел бы не нет саму идею использования класса Array как шаблона.
Поэтому нужно найти другое решение. Попробуем добиться того, чтобы оператор вывода работал независимо от типа экземпляра массива.
ostream& operator<< (ostream&, Array<T>&);
Чтобы этот оператор работал, нужно так объявить operator<<, чтобы он стал функцией шаблона:
template <class T> ostream& operator<< (ostream&, Array<T>&)
Теперь operator<< является функцией шаблона и его можно использовать в выполнении класса. В листинге 19.4 показано объявление шаблона Array, дополненное объявлением функции оператора вывода operator<<.
Листинг 18.4. Использование оператора вывода
1: #include <iostream.h>
2:
3: const int DefaultSize = 10;
4:
5: class Animal
6: {
7: public:
8: Animal(int);
9: Animal();
10: ~Animal() { }
11: int GetWeight() const { return itsWeight; }
12: void Display() const { cout << itsWeight; }
13: private:
14: int itsWeight;
15: };
16:
17: Animal::Animal(int weight):
18: itsWeight(weight)
19: { }
20:
21: Animal::Animal():
22: itsWeight(0)
23: { }
24:
25: template <class T> // объявляем шаблон и параметр
26: class Array // параметризованный класс
27: {
28: public:
29: // конструкторы
30: Array(int itsSize = DefaultSize);
31: Array(const Array &rhs);
32: ~Array() { delete [] pType; }
33:
34: // операторы