• Инициализируя разные массивы, можем получить объекты класса Array_ref
• Обновляя пару (p, size
reset(), можем изменить размер существующего класса Array_ref (многие алгоритмы требуют указания поддиапазонов).• В классе Array_ref
Array_ref очень напоминает диапазон, заданный двумя итераторами.Класс Array_ref
array из стандартной библиотеки (см. раздел 20.9).Для того чтобы облегчить создание объектов класса Array_ref
template
{
return (pp) ? Array_ref
}
Если мы инициализируем объект класса Array_ref
Polygon[10] в указатель Shape* (ужасная проблема, описанная в разделе 25.4.2), но иногда мы должны просто доверять программисту.Мы решили проявить осторожность в отношении нулевых указателей (поскольку это обычный источник проблем) и пустых векторов.
template
{
return (v.size()) ? Array_ref
Array_ref(0,0); }
Идея заключается в том, чтобы передавать вектор элементов. Мы выбрали класс vector
Array_ref может оказаться полезным. Причина заключается в том, что он обладает ключевыми свойствами, присущими контейнерам, которые здесь можно использовать (например, контейнерам, основанным на пулах; см. раздел 25.3.3).В заключение предусмотрим обработку встроенных массивов в ситуациях, в которых компилятор знает их размер.
template
{
return Array_ref
}
Забавное выражение T(&pp)[s]
pp ссылкой на массив из s элементов типа T. Это позволяет нам инициализировать объект класса Array_ref массивом, запоминая его размер. Мы не можем объявить пустой массив, поэтому не обязаны проверять, есть ли в нем элементы.Polygon ar[0]; // ошибка: элементов нет
Используя данный вариант класса Array_ref
void better(Array_ref
{
for (int i = 0; i
}
void f(Shape* q, vector
{
Polygon s1[10];
Shape s2[20];
// инициализация
Shape* p1 = new Rectangle(Point(0,0),Point(10,20));
better(make_ref(s0)); // ошибка: требуется Array_ref
better(make_ref(s1)); // ошибка: требуется Array_ref
better(make_ref(s2)); // OK (преобразование не требуется)
better(make_ref(p1,1)); // OK: один элемент
delete p1;
p1 = 0;
better(make_ref(p1,1)); // OK: нет элементов
better(make_ref(q,max)); // OK (если переменная max задана корректно)
}
Мы видим улучшения.
• Код стал проще. Программисту редко приходится заботиться о размерах объектов, но когда это приходится делать, они задаются в специальном месте (при создании объекта класса Array_ref
• Проблема с типами, связанная с преобразованиями Circle[]
Shape[] и Polygon[], и Shape[], решена.• Проблемы с неправильным количеством элементов объектов s1
s2 решаются неявно.• Потенциальная проблема с переменной max (и другими счетчиками элементов, необходимыми для использования указателей) становится явной — это единственное место, где мы должны явно указать размер.
• Использование нулевых указателей и пустых векторов предотвращается неявно и систематически.
25.4.4. Наследование и контейнеры