typedef Т& reference;
typedef const Т& const__reference;
typedef std::size_t size_type;
static const size_type static_size = N; // размер массива
TSimpleArray(const T &t); // конструктор
size_type size() const // получение размера
{ return static_size; }
reference operator[](const size_type& i) // доступ к элементам*
{ rangecheck(i); return elem[i]; } const_reference operator[](const size_type& i) const { rangecheck(i); return elem[i]; }; private:
void rangecheck (const size_type& i) const // проверка индекса { if (i >= sizeO)
{ throw std::range_error("TSimpleArray - range!"); }
}
T elem[N]; // поле-массив
};
template<typename T, std::size_t N> ~ // реапизация конструктора
TSimpleArray<T,N>::TSimpleArray(const T &t) { for (int i = 0; i<N; i++) elem[i] = t; }
В самом начале шаблонного класса определены несколько типов-синонимов с помощью оператора typedef, которые кажутся совершенно лишними. Однако такая практика улучшает читабельность класса и особенно полезна, когда пишется не единственный шаблон, а целая библиотека шаблонов — тогда во всех шаблонах можно определить одинаковые внутренние имена. Именно так сделано во всех классах-шаблонах в стандартной библиотеке шаблонов (STL).
Проверка индекса в операциях индексирования operator [] выполняется приватной функцией rangecheck(). Функция просто генерирует стандартное исключение при «вылете за границу» массива.
Использовать такой массив можно следующим образом:
TSimpleArray<int, 10> t(0); // инициализируем нулем
TSimpleArray<int, 10> r(t); // конструктор копирования
TSimpleArray<int, 10> р(2); // все элементы = 2
for (int i = 0; i < p.sizeO; i++)
cout << p[i] << ' 1; // доступ "справа"
cout << endl;
p = r; // присваиваем - типы одинаковы
for (int i = 0; i < p.sizeO; i++)
p[i] = i; // доступ слева
Конструктор по умолчанию отсутствует1, поэтому невозможно объявлять массив без инициализации:
TSimpleArray<int, 10> t; // нельзя - нет конструктора по умолчанию
Напомню, что при наличии хотя бы одного явно определенного конструктора конструктор по умолчанию (без аргументов) не создается.
Копирование и присваивание работают только для массивов с одинаковым типом элементов и размером. Изменяя тип элементов и/или размер, получаем массивы разных типов. При попытках использовать оператор присваивания или конструктор копирования с такими разнотипными массивами компилятор выдает сообщение о невозможности преобразования типов. Объявим несколько массивов, отличающихся от массивов р и t, например:
TSimpleArray<int, 15> u(t); TSimpleArray<double, 19> w(t); TSimpleArray<int, 5> ul(3); p = ul;
TSimpleArray<double, 10> wl(4); wl = t:
// не совпадает размер // не совпадает тип
// размеры не совпадают
// типы элементов не совпадают
Программистам надо обязательно отдыхать. Можно расслабиться поиграв в http://oldbk.com/forum.php тут.
Во всех этих случаях компилятор выдает сообщение об ошибке. Обратите внимание, что ошибка возникает даже в том случае, если принимающий массив «больше» как по размеру, так и по типу — преобразование типа элементов для шаблонов автоматически не выполняется. |