|
Программирование >> Аргументация конструирования
vi student * pS) p3->seinesterHour3 = 10; pS->gpa = 3.6; pS->addCoYirse(3, 4.0); вызываем функцию-член int main(int argc, char* pArgs[)) { Student s; s.gpa = 0.0; отображаем значение gpa перед вызовом someFn cout Значение s.gpa = s.gpa \n ; передаем адрес нашего объекта cout Вызываем функцию someFn(Student)\п ; someFn(&s); теперь значение gpa после вызова someFn равно 3.0 cout Значение s.gpa = s.gpa \n ; return 0; Теперь вместо создания одной копии функции () передается адрес существующего объекта s (можно сказать, что вместо копии объекта функции передается копия адреса объекта). Результат работы этой функции будет следующим: Значение s.gpa = О Вызываем функцию someFn(Student) Значение s.gpa =3.0 Передача объекта по ссылке Оператор ссылки описан в главе 9, Второе знакомство с указателями , и может применяться для пользовательских объектов так же, как и для всех остальных. finclude Student.h Все то же самое, но осуществляем передачу по ссылке void refS) = 10; refS.gpa = 3.0; refS.addCourse(3, 4.0); вызываем функцию-член Student s; in (int argc, char* pAxgs[;i) someFn(s); return 0; В этой программе в функцию someFn () передается не копия объекта, а ссылка на него. Изменения, внесенные функцией someFn () в s, сохраняются внутри raain(). Передача объекта по ссылке фактически передает в функцию адрес объекта s; при этом C++ самостоятельно разыменовывает переданный указатель. Проблемы, возникающие при работе с указателями на простые переменные, распространяются и на указатели на объекты. В частности, необходимо гарантировать, что указатель ссылается на существующий корректный объект. Так, нельзя возвращать указатель на локально определенный объект, как это сделано в данном примере: MyClass* myFuncf) эта функция не будет работать правильно MyClass mc; MyClass* рМС = uir.c; return рМС; После возврата из объект выходит из области видимости, а значит, указатель, который возвращает myFunc (), указывает на несуществующий объект. Использование кучи позволяет решить эту проблему: MyClass* myFunc () MyCl;..4s* pMC = new MyClass; return pMC; С помощью кучи можно выделять память для объектов в самых разнообразных ситуациях. использование связанных списков Связанный список является второй по распространенности структурой после массива. Основным преимуществом связанного списка служит отсутствие необходимости задавать фиксированный размер на этапе компиляции: связанный список может уменьшаться и увеличиваться в зависимости от потребностей программы. Цена такой гибкости - сложность обращения, поскольку использовать элементы связанного списка гораздо сложнее, чем элементы массива. Массив Массив очень удобен для хранения набора объектов, так как позволяет просто и быстро обратиться к отдельным его элементам: MyClass mc[100]; выделяем место под 100 элементов тс [п ; иться )-му элементу списка Однако у массивов есть много весомых недостатков. Основным недостатком массивов является фиксированность их длины. Можно спрогнозировать количество элементов в массиве, необходимое для работы программы, однако, будучи однажды определенным, это количество не может быть изменено. void fn(int nSize) ( создаем массив из п объектов MyClass MyClass* рМС = new МуС1азз[п1; теперь длина массива не может забывайте инициализировать указатели значением 0. Указатель, содержащий ноль, называется пустым . Обычно попытка обращения по адресу 0 вызывает аварийную остановку программы. Преобразование целочисленного нуля в тип не обяза- тельно. C++ воспринимает 0 как значение любого типа (в частности, как универсальный указатель ). Приведенная ниже простая функция, добавляющая переданный ей аргумент в начало списка, поможет вам разобраться со связанными списками. voi kableClass* pLC) pLC->pNext = pHead pHead = pLC; Кроме того, все элементы массива должны быть одного типа. Невозможно хранить объекты типа Myciass и YourClass в одном массиве. И наконец, крайне трудно вставить объект в середину массива. Для добавления или удаления объекта программа должна перенести соседние элементы вперед или назад, чтобы создать или уничтожить пустое место в середине массива. (Представьте себе процесс вставки дома внутрь застроенного квартала, и вы поймете, о чем я говорю.) Однако существует и альтернативная структура данных, лишенная указанных недостатков. Конструкция, которая может заменить массив, называется связанным списком. Связанный список Дети, держащие друг друга за руки и переходящие дорогу, используют тот же принцип, что и связанный список. В связанном списке каждый объект связан со следующим объектом в цепочке. Учитель в этом случае представляет собой головной элемент, указывающий на первый элемент списка. Не всякий класс может быть использован для создания связанного списка. Связываемый класс объявляется так, как показано в приведенном ниже фрагменте. class LinkableClass { public: LinkableClass* pNext; прочие члены класса Ключевым в этом классе является указатель на объект класса LinkableClass. На первый взгляд несколько необычно выглядит то, что класс содержит указатель сам на себя. В действительности в этом объявлении подразумевается, что каждый объект класса содержит указатель на другой объект этого же класса. Указатель pNext и есть тот элемент, с помощью которого дети объединяются в цепочки. Фигурально выражаясь, можно сказать, что список детей состоит из некоторого количества объектов, каждый из которых имеет тип ребенок . Каждый ребенок указывает на следующего ребенка. Головной указатель является указателем типа LinkableClass*, и если продолжать аналогию с цепочкой детей, то можно сказать, что учитель указывает на объект класса ребенок (любопытно отметить, что сам учитель не является ребенком - головной указатель не обязательно должен иметь тип LinkableClass).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |