|
Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Передача объекта по ссылке
Оператор ссылки описан в главе 9, "Второе знакомство с указателями", и может применяться для пользовательских объектов так же, как и для всех остальных.
//Все то же самое, но осуществляем передачу по ссылке void refS)
refS.gpa = 3.0;
} = 10;
4.0); //вызываем функцию-член
int argc, char* {
return 0; } В этой программе в функцию someFn () передается не копия объекта, а ссылка на него. Изменения, внесенные функцией s ome Fn () в сохраняются внутри in (). Передача объекта по ссылке фактически передает в функцию адрес объекта s; при этом C++ самостоятельно разыменовывает переданный указатель.
164 Часть "Классическое" программирование
MyClass* { //эта функция не будет работать правильно MyClass MyClass* = return } После возврата из объект выходит из области видимости, а значит, который возвращает (), указывает на несуществующий объект. Использование кучи позволяет решить эту проблему: MyClass*
pMC new MyClass; return pMC; }
С помощью кучи можно выделять память для объектов в самых разнооб- разных ситуациях.
использованиесвязанныхсписков Связанный список является второй по распространенности структурой после мас- сива. Основным преимуществом связанного списка служит отсутствие необходимости задавать фиксированный размер на этапе компиляции: связанный список может уменьшаться и увеличиваться в зависимости от потребностей программы. Цена такой гибкости — сложность обращения, поскольку использовать элементы связанного спи- ска гораздо сложнее, чем элементы массива.
Массив Массив очень удобен для хранения набора объектов, так как позволяет просто и быстро обратиться к отдельным его элементам: MyClass //выделяем место под 100 элементов [п ; / к элементу списка Однако у массивов есть много весомых недостатков. Основным недостатком массивов является фиксированность их длины. Можно спрогнозировать количество элементов в массиве, необходимое для работы програм- мы, однако, будучи однажды определенным, это количество не может быть изменено.
( //создаем массив из п объектов //MyClass MyClass* pMC = new //теперь длина массива не может
Глава 15. Создание указателей на объекты 165
} Кроме того, все элементы массива должны быть одного типа. Невозможно хранить объекты типа и YourClass в одном массиве. И наконец, крайне трудно вставить объект в середину массива. Для добавления или удаления объекта программа должна перенести соседние элементы вперед или назад, чтобы создать или уничтожить пустое место в середине массива. (Представьте себе про- цесс вставки дома внутрь застроенного квартала, и вы поймете, о чем я говорю.) Однако существует и альтернативная структура данных, лишенная указанных недос- татков. Конструкция, которая может заменить массив, называется связанным списком.
Связанный список Дети, держащие друг друга за руки и переходящие дорогу, используют тот же принцип, что и связанный список. В связанном списке каждый объект связан со сле- дующим объектом в цепочке. Учитель в этом случае представляет собой головной элемент, указывающий на первый элемент списка. Не всякий класс может быть использован для создания связанного списка. ваемый класс объявляется так, как показано в приведенном ниже фрагменте. class LinkableClass
LinkableClass* //прочие члены класса }; Ключевым в этом классе является указатель на объект класса LinkableClass. На первый взгляд несколько необычно выглядит то, что класс содержит указатель сам на себя. В действительности в этом объявлении подразумевается, что каждый объект класса содержит указатель на другой объект этого же класса. Указатель pNext и есть тот элемент, с помощью которого дети объединяются в це- почки. Фигурально выражаясь, можно сказать, что список детей состоит из некото- рого количества объектов, каждый из которых имеет тип "ребенок". Каждый ребенок указывает на следующего ребенка. Головной указатель является указателем типа LinkableClass* , и если продолжать аналогию с цепочкой детей, то можно сказать, что учитель указывает на объект класса "ребенок" (любопытно отметить, что сам учитель не является ребенком — головной указатель не обязательно должен иметь тип LinkableClass). забывайте инициализировать указатели значением 0. Указатель, со- держащий ноль, называется "пустым". Обычно попытка обращения по адресу 0 вызывает аварийную остановку программы.
Преобразование целочисленного нуля в тип не обяза- тельно. C++ воспринимает 0 как значение любого типа (в частности, как "универсальный указатель").
Приведенная ниже простая функция, добавляющая переданный ей аргумент в на- чало списка, поможет вам разобраться со связанными списками. void pLC) { pLC->pNext = pHead pHead = pLC;
Часть III, "Классическое" программирование Другие операции над связанным списком Добавление объекта в начало списка является самой простой операцией со связан- ным списком. Гораздо сложнее добавить элемент в конец списка: void pLC) { на начало списка pCurxent = //будем просматривать список, пока не найдем элемент списка — он должен содержать //О указателе != f ) 0] { pCurrent pCurrent->pNext; } //теперь заставим этот объект указывать на pCurrent->pNext = pLC; //присвоим 0 указателю на следующий объект //в новом конечном пометив его //как последний в списке = } Тело функции addTail () начинается с просмотра всего списка с самого начала до элемента, значение поля которого равно нулю. Этот элемент и является послед- ним в списке. После этого функция addTail () добавляет объект pLC* к концу списка. (В действительности приведенная функция содержит одну ошибку. Кроме провер- ки элементов списка на равенство нулю, необходимо проверять и головной элемент списка pHead. Ноль в pHead означает, что список пуст.) Функция remove () схожа с предыдущей. Она удаляет указанный объект из списка и возвращает 1, если удаление прошло без ошибок, и 0 в противном случае. void pLC) { pCurrent = pHead; //если список пуст, мы не найдем в нем *pLC if (LinkableClass*) 0) { return 0; }
весь список до конца в поисках элемента
{ //если следующий объект является искомым объектом { заставим текущий объект указывать //на следующий за ним pCurrent->pNext = //это не обязательно, но лучше удалить указатель //на следующий объект в удаляемом элементе pLC->pNext = return 1;
return 0; }
Глава 15. Создание указателей на объекты 167
|
Последнее изменение этой страницы: 2019-04-19; Просмотров: 231; Нарушение авторского права страницы