18.6.1. Порождение класса, контролирующего выход за границы массива
18.6.1. Порождение класса, контролирующего выход за границы массива
В функции try_array() из раздела 16.13, предназначенной для тестирования нашей предыдущей реализации шаблона класса Array, есть две инструкции:
int index = iA.find( find_val );
Type value = iA[ index ];
find() возвращает индекс первого вхождения значения find_val или -1, если значение в массиве не найдено. Этот код некорректен, поскольку в нем не проверяется, что не была возвращена -1. Поскольку -1 находится за границей массива, то каждая инициализация value может привести к ошибке. Поэтому мы создадим подтип Array, который будет контролировать выход за границы массива, – Array_RC и поместим его определение в заголовочный файл Array_RC.h:
#ifndef ARRAY_RC_H
#define ARRAY_RC_H
#include "Array.h"
template class Type
class Array_RC : public virtual ArrayType {
public:
Array_RC( int sz = ArraySize )
: Array Type( sz ) {}
Array_RC( const Array_RC& r );
Array_RC( const Type *ar, int sz );
Type& operator[]( int ix );
};
#endif
Внутри определения производного класса каждая ссылка на спецификатор типа шаблона базового должна быть квалифицирована списком формальных параметров:
Array_RC( int sz = ArraySize )
: ArrayType( sz ) {}
Такая запись неправильна:
// ошибка: Array - это не спецификатор типа
Array_RC( int sz = ArraySize ) : Array( sz ) {}
Единственное отличие поведения класса Array_RC от базового состоит в том, что оператор взятия индекса контролирует выход за границы массива. Во всех остальных отношениях можно воспользоваться уже имеющейся реализацией шаблона класса Array. Напомним, однако, что конструкторы не наследуются, поэтому в Array_RC определен собственный набор из трех конструкторов. Мы сделали класс Array_RC виртуальным наследником класса Array, поскольку предвидели необходимость множественного наследования.
Вот полная реализация функций-членов Array_RC, находящаяся в файле Array_RC.C (определения функций класса Array помещены в заголовочный файл Array.C, поскольку мы пользуемся моделью конкретизации шаблонов с включением, описанной в разделе 16.18):
#include "Array_RC.h"
#include "Array.C"
#include assert.h
template class Type
Array_RC Type ::Array_RC( const Array_RCType &r )
: Array Type( r ) {}
template class Type
Array_RC Type ::Array_RC( const Type *ar, int sz )
: Array Type( ar, sz ) {}
template class Type
Type &Array_RC &Type&::operator[]( int ix ) {
assert( ix = 0 && ix & Array &Type&::_size );
return ia[ ix ];
}
Мы квалифицировали обращения к членам базового класса Array, например к _size, чтобы предотвратить просмотр Array до момента конкретизации шаблона:
Array Type::_size;
Мы достигаем этого, включая в обращение параметр шаблона. Таким образом, имена в определении Array_RC разрешаются тогда, когда определяется шаблон (за исключением имен, явно зависящих от его параметра). Если встречается неквалифицированное имя _size, то компилятор должен найти его определение, если только это имя не зависит явно от параметра шаблона. Мы сделали имя _size зависящим от параметра шаблона, предварив его именем базового класса Array. Теперь компилятор не будет пытаться разрешить имя _size до момента конкретизации шаблона. (В определении класса Array_Sort мы приведем другие примеры использования подобных приемов.)
Каждая конкретизация Array_RC порождает экземпляр класса Array. Например:
Array_RCstring sa;
конкретизирует параметром string как шаблон Array_RC, так и шаблон Array. Приведенная ниже программа вызывает try_array() (реализацию см. в разделе 16.13), передавая ей объекты подтипа Array_RC. Если все сделано правильно, то выходы за границы массивы будут замечены:
#include "Array_RC.C"
#include "try_array.C"
int main()
{
static int ia[] = { 12,7,14,9,128,17,6,3,27,5 };
cout "конкретизация шаблона класса Array_RC int ";
try_array( iA );
return 0;
}
После компиляции и запуска программа печатает следующее:
конкретизация шаблона класса Array_RCint
try_array: начальные значения массива
( 10 ) 12, 7, 14, 9, 128, 17
6, 3, 27, 5
try_array: после присваиваний
( 10 ) 128, 7, 14, 9, 128, 128
6, 3, 27, 3
try_array: почленная инициализация
( 10 ) 12, 7, 14, 9, 128, 128
6, 3, 27, 3
try_array: после почленного копирования
( 10 ) 12, 7, 128, 9, 128, 128
6, 3, 27, 3
try_array: после вызова grow
( 10 ) 12, 7, 128, 9, 128, 128
6, 3, 27, 3, 0, 0
0, 0, 0, 0
искомое значение: 5 возвращенный индекс: -1
Assertion failed: ix = 0 && ix & _size
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
5.2. Границы фрейма
5.2. Границы фрейма Обращаю ваше внимание на то, что в описанном выше примере каждый фрейм имеет границу (см. рис. 5.1). Границей фрейма можно управлять, как и любыми другими элементами фрейма. Для этого существует несколько атрибутов элемента FRAMESET, позволяющих настраивать
Границы
Границы Для задания границ вы можете использовать следующие свойства: border, border-collapse и border-spacing.Свойство border задает стиль границы и размер. Стили границ будут подробно рассмотрены в следующих разделах. Размер границы задается целым числом и с указанием единицы
9.7. Границы
9.7. Границы Для всех элементов страницы вы можете задать границы, а также установить их ширину, цвет и стиль. Начнем изучение границ со свойства
Цвет границы
Цвет границы Как и для ширины, для задания цвета существует четыре свойства для четырех сторон: border-top-color, border-right-color, border-bottom-color, border-left-color и сокращенная запись – border-color. Они задают цвет верхней, правой, левой и нижней границ соответственно. Для всех этих свойств вы можете
Границы элементов
Границы элементов borderЗадает все свойства границ элемента страницы в один прием.Заменяет атрибуты border-color, border-style и border-width. Значения этих атрибутов могут располагаться в любом порядке.border: [{border-color}] [{border-style}] [{border-width}];Значение по умолчанию medium none. Поддерживается IE начиная
3.1.4. Внутренние границы
3.1.4. Внутренние границы В Unix действует предположение о том, что программист знает лучше (чем система). Система не остановит пользователя и не потребует какого-либо подтверждения при выполнении опасных действий с данными, таких как ввод команды rm -rf *. С другой стороны, Unix
3.1.4. Внутренние границы
3.1.4. Внутренние границы В Unix действует предположение о том, что программист знает лучше (чем система). Система не остановит пользователя и не потребует какого-либо подтверждения при выполнении опасных действий с данными, таких как ввод команды rm -rf *. С другой стороны, Unix
Границы и заливка
Границы и заливка По умолчанию ячейки не имеют видимых границ: вы видите тонкие серые линии, разграничивающие ячейки, но эти линии не отображаются при печати документа. Иногда же требуется, чтобы напечатанная таблица имела четкие границы (рис. 3.10). Рис. 3.10. Пример
Границы
Границы Рассмотрим, как можно создать видимые границы ячейки, которые будут отображаться при печати.Прежде всего напомню, что перед какими-либо преобразованиями ячейки (или диапазон) должны быть выделены.Обратите внимание на кнопку Границы, расположенную в группе Шрифт
18.6.2. Порождение класса отсортированного массива
18.6.2. Порождение класса отсортированного массива Вторая наша специализация класса Array – отсортированный подтип Array_Sort. Мы поместим его определение в заголовочный файл Array_S.h:#ifndef ARRAY_S_H_#define ARRAY_S_H_#include "Array.h"template class Typeclass Array_Sort : public virtual Array Type {protected:void set_bit() { dirty_bit = true; }void
3. Порождение объяснений.
3. Порождение объяснений. Различие в механизмах поиска решений у человека, специалиста по решению определенного класса задач и у интеллектуальной системы приводит к появлению эффекта непонимания. Видя окончательный результат деятельности интеллектуальной системы,
Таблицы и границы
Таблицы и границы ТаблицаВсе мы интуитивно понимаем, о чем идет речь, когда произносится слово «таблица», но будет лучше, если мы все-таки договоримся о терминах и будем их употреблять в одинаковом смысле.Под таблицей понимается набор строк и столбцов, пересечения
Границы и заливка
Границы и заливка Для применения к выделенному фрагменту границ или заливки можно использовать следующие кнопки в группе Абзац вкладки Главная. Заливка. Позволяет выполнить заливку выбранным фоном. Щелчок на кнопке сразу же применяет текущий цвет заливки для текущего