|
Программирование >> Инициализация объектов класса, структура
int oops in error() { mumble ... goto end; правильно: объявление во вложенном блоке int ix = 10; ... код, использующий ix end: ; инструкции во вложенный блок: Причина такого ограничения та же, что и для объявлений внутри блока switch: компилятор должен гарантировать, что для объявленного объекта конструктор и деструктор либо выполняются вместе, либо ни один из них не выполняется. Это и достигается заключением объявления во вложенный блок. Переход назад через объявление, однако, не считается ошибкой. Почему? Перепрыгнуть через инициализацию объекта нельзя, но проинициализировать один и тот же объект несколько раз вполне допустимо, хотя это может привести к снижению эффективности. Например: int oops in error() { mumble ... goto end; ошибка: переход через объявление int ix = 10; ... код, использщий ix end: ; Правильная реализация функции помещает объявление ix и использующие его переход назад через объявление не считается ошибкой. void mumble ( int max size ) { begin: int sz = get size(); if ( sz <= 0 ) { в1дать предупреждение . . . goto end; else if ( sz > max size ) получить новое значение sz goto begin; { правильно: переход через це блок int ia = new int[ sz ]; doit( ia, sz ) delete [] ia; end: Использование инструкции goto резко критикуется во всех современных языках программирования. Ее применение приводит к тому, что ход выполнения программы становится трудно понять и, следовательно, такую программу трудно модифицировать. В большинстве случаев goto можно заменить на инструкции if или циклы. Если вы все-таки решили использовать goto, не перескакивайте через большой фрагмент кода, чтобы можно было легко найти начало и конец вашего перехода. 5.11. Пример связанного списка М1 завершали главы 3 и 4 примерами для введения читателя в механизм классов С++. В конце этого раздела мы покажем, как разработать класс, представляющий собой односвязный список. (В главе 6 мы рассмотрим двусвязный список, являющийся частью стандартной библиотеки.) Если вы в первый раз читаете эту книгу, то можете пропустить данный раздел и вернуться к нему после чтения главы 13. (Для усвоения этого материала нужно представлять себе механизм классов С++, конструкторы, деструкторы и т.д. Если вы плохо знаете классы, но все же хотите продолжить чтение данного раздела, мы рекомендуем прочесть пункты 2.3 и 3.15. Список представляет собой последовательность элементов, каждый из которых содержит значение некоторого типа и адрес следующего элемента (причем для последнего из них адрес может быть нулевым). К любой такой последовательности всегда можно добавить еще один элемент (хотя реальная попытка подобного добавления может закончиться неудачно, если отведенная программе свободная память исчерпана). Список, в котором нет ни одного элемента, называется пустым. Какие операции должен поддерживать список? Добавление (insert), удаление (remove) и поиск (find) определенных элементов. Кроме того, можно запрашивать размер списка (size), распечатывать его содержимое (display), проверять равенство двух списков. Мы покажем также, как инвертировать (reverse) и сцеплять (concatenate) списки. Простейшая реализация операции size() перебирает все элементы, подсчитывая их количество. Более сложная реализация сохраняет размер как член данных; она намного вызов mylist.insert (pointer to 3, 5); изменит наш список так: 1 1 2 3 5 8 Чтобы обеспечить подобную возможность, нам необходимо дать пользователю способ получения адреса определенного элемента. Одним из способов может быть использование функции find() - нахождение элемента с определенным значением: pointer to 3 = mylist.find( 3 ); find() принимает в качестве параметра значение из списка. Если элемент с таким значением найден, то возвращается его адрес, иначе find() возвращает 0. Может быть два специальных случая вставки элемента: в начало и в конец списка. Для insert front( value ); этого требуется только задание значения: 1nsert end( value ); Предусмотрим следующие операции удаления элемента с заданным значением, первого remove( value ); remove front(); элемента и всех элементов списка: remove all(); эффективнее, однако требует некоторого усложнения операций insert() и remove() для поддержки размера в актуальном состоянии. Mi выбрали второй вариант реализации функции size() и храним размер списка в члене данных. Mi предполагаем, что пользователи будут достаточно часто применять эту операцию, поэтому ее необходимо реализовать как можно более эффективно. (Одним из преимуществ отделения открытого интерфейса от скрытой реализации является то, что если наше предположение окажется неверным, мы сможем переписать реализацию, сохранив открытый интерфейс - в данном случае тип возвращаемого значения и набор параметров функции size() - и программы, использующие эту функцию, не нужно будет модифицировать.) Операция insert() в общем случае принимает два параметра: указатель на один из элементов списка и новое значение, которое вставляется после указанного элемента. Например, для списка I1 1 2 3 8
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |