Г. Шилтд - Самоучитель C++ (DJVU), страница 9
Описание файла
DJVU-файл из архива "Г. Шилтд - Самоучитель C++ (DJVU)", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр DJVU-файла онлайн
Распознанный текст из DJVU-файла, 9 - страница
Конструктор вызывается тогда, когда создается объект оЬ. Объект, в свою очередь, создается при выполнении инструкции объявления объекта. Важно понимать, что в С++ инструкция объявления переменной является "инструкцией действия". При программировании на С инструкции объявления переменных понимаются просто как создание переменных. Однако в С++, поскольку объект может иметь конструктор, инструкция объявления переменной может вызывать выполнение записанных в конструкторе действий.
Обратите внимание, как определяется конструктор аус!авяО. Как уже говорилось, он не имеет возвращаемого значения. В соответствии с формальными правилами синтаксиса С++ конструктор не должен иметь возвращаемого значения. Для глобальных объектов конструктор объекта вызывается тогда, когда начинается выполнение программы. Для локальных объектов конструктор вызывается всякий раз при выполнении инструкции объявления переменной.
Функцией, обратной конструктору, является деструктор ('г(езписгог). Эта функция вызывается при удалении объекта. Обычно при работе с объектом в момент его удаления должны выполняться некоторые действия. Например, при создании объекта для него вьщеляется память, которую необходимо освободить при его удалении. Имя деструктора совпадает с именем класса, но с символом (тильда) в начале. Пример класса с деструктором: () ьис1нс)е <(оз1геаго > из(иа пагиезрасе вссов; с1азз гиус1азв ( (пг а; рнЬ11е: тус1азз (); О конструктор -вуе1азз (); П деструктор ъотс( зЬон(); ыус1азз: паус1азз() ( сочв « "Содержимое конструктораМ"' а = 1О! Самоучитель С+~- пгус1азз: ."-гкус1азз () ( соус « "удаление... ~п" г чоЫ гпус1азз: ."зйои() сопс « а « "Ю'> ) тпс гиьп() ( пус1азз оЬ; оЬ.зЬэи (); "еспгт~ О; Деструктор класса вызывается при удалении объекта. Локальные объекты удаляются тогда, когда они выходят из области видимости.
Глобальные объекты удаляются при завершении программы. Адреса конструктора и деструктора получить невозможно. Фактически как конструктор, так и деструктор могут выполнить любой тип операции. Тем не менее считается, что код внутри этих функций не должен делать ничего, не имеющего отношения к инициализации или возвращению обьектов в исходное состояние. Например, конструктор в предшествующем примере мог бы рассчитать число р( с точностью до 100 знаков после запятой.
Однако применение конструктора или деструктора для действий, прямо не связанных с инициализацией, является очень плохим стилем программирования и его следует избегать. 1. Вспомните, что в созданном в главе 1 классе атас)(для установки переменной индекса стека требовалась функция инициализации.
Это именно тот тип действия, для выполнения которого и придуман конструктор. Здесь представлена улучшенная версия класса Маей, где для автоматической инициализации объекта стека при его создании используется конструктор: ()1пс1ибе <гозттеаггг> из(па пагпезрасе зЫ; ()с)ейьпе Я)ХЕ 1О Глана 2, Введение в классы Объявление класса ясас)< для символов с1азз ясас).
( сЬаг васк(51ХЕ); 1/ содержит стек 1пс поз; 1! индекс верщины стека рпЬ11с: я аск.()' /~ конструктор чо16 рияЬ(сЬаг сЬ)," // помещает в стек символ сЬат рор(); 1~ выталкивает из стека символ 1! Инициализация стека з~асИ.":я~ас)~() ( сопс « "Работа конструктора стека ~п"; йоз=О) Помещение символа в стек чоЫ з~ас1:: рпзЬ (сЬак сЬ) ( (1оя==В1ЕЕ) ( сопс « "Стек полон"1 лесы сп; ) ясса(соя1=сЬ; воя++; Выталкивание символа из стека сЬаг запас)~::рор() ( 1й (Соя==-О) ( сопп « "Стек пуст"; гесптп О; // возврат нуля при пустом стеке ) 105 — ~ геепгп я~с)<(1оз]; 1пспаз.п ( ) ( образование двух автоматически инициализируемых стеков зсас). 51, 52; 1пс 1; 51.рияЬ( 'а') р. 52.рцяЬ('х'); 51.рпяЬ('Ь']; Самоучитель С++ а2.рцвн( ' у' ); а1.рцап ('с' ); а2.рца~('г'); Рог(1=0; 1<зр 1++) сонг « "символ из а1:" « а1.рор() « "'~п"; ог(1=0: 1<зг 1++) соцс « "символ из а2:" « а2.рор() « "~п"; геГв гп О1 Обратите внимание, что теперь вместо отдельной, специально вызываемой программой функции задача инициализации выполняется конструктором автоматически.
Это важное положение. Если инициализация выполняется автоматически при создании объекта, то это исключает любую возможность того, что по ошибке инициализация не будет выполнена. Вам, как программисту, не нужно беспокоиться об инициализации — она автоматически выполнится при появлении объекта. 2. В следующем примере показана необходимость не только конструктора, но и деструктора. В примере создается простой класс для строк, который содержит саму строку и ее длину. Когда создается объект аЫуре, для хранения строки выделяется память, и начальная длина строки устанавливается равной нулю. Когда объект в1г(уре удаляется, эта память освобождается. Й1пс1цбе <ъозггеаш> ()1пс1цс1е <сатппа> ((1гс1ц<)е <саГб11Ь> из1пд пап1езрасе аго; ()бег1пе Е)У.Е 255 с1аьа атттурс с)заг *р; )пг 1еп; рц)з11с." аггсуре (); // конструктор -агггуре (); // деструктор чо1д вес(снаг *рог); чоЫ в)зон(); // Инициализация объекта строка згггуре::агг1уре () р=(сваг ') тпа11ос (ЯХЕЕ); г'(!р) соцГ « "Ошибка выделения памяти~в"; ех)г (1); Глава 2.
Введение в классы Освобождение памяти при удалении объекта строка зтгЕуре::-зег~уре() соШ « "Освобождение памяти по адресу р~п"; 1 гее (р); уотст зсгтуре:: зеГ (сЬаг *рег) ( 1г (зег1еп(р) > =.31КЕ) ( сопк << "Строка слишком велика~в"; гесппп; ) зсгсру(р, рсг): 1еп=зег1еп(р) р уотс( зегГуре:: зЬои () сопс « р « " — длина: " « 1епт сопб « "'и"т ) тпс тоагп () вбгвуре з1, з2; з1.зев("Это проверка"); з2.
зес ("Ыне нравится С++") з1.зЬом(); з2. зЬом(); гетигп О; В этой программе для выделения и освобождения памяти используются функции шаПое() и тгее(). Хотя этот пример совершенно правилен, как вы увидите далее в этой книге, в С++ есть и иной путь управления распределением динамической памяти. В предыдущей программе заголовочные файлы библиотечных функций языка С оформлены в соответствии с новым стилем оформления заголовков.
Как уже упоминалось в главе т, если ваш компилятор не поддерживает такие за- Гпввв 2. Введение в классы !. Измените класс явеые (см. упражнения гл. () так, чтобы провести инициализацию с помощью конструктора. 2. Создайте класс в(ориа(сЬ для имитации секундомера. Используйте конструктор для начальной установки секундомера в О.
Образуйте две функции-члена в$агйО и в(ор() соответственно для запуска и остановки секундомера. Включите в класс и функцию-член зйочЦ для вывода на экран величины истекшего промежутка времени. Также используйте деструктор для автоматического вывода на экран времени, прошедшего с момента создания объекта класса в(орва(сЬ, до его удаления. (Для простоты время приведите в секундах.) 3. Что неправильно в конструкторе, показанном в следующем фрагменте? с(авв яашр(е ( с(оиЫе а, Ь, с; раЬ11о: с1оиЫе яашр1е (); // ошибка, почему? )' 2.2. Конструкторы с параметрами Конструктору можно передавать аргументы.
Для этого просто добавьте необходимые параметры в объявление и определение конструктора. Затем при объявлении объекта задайте параметры в качестве аргументов. Чтобы понять, как это делается, начнем с короткого примера: ((1гс1ип(е <1овскеа~п> аяггд гашеярасе япб; с1аяя тустаяя ( 1оп а; роЬ11с: шус1аяя(ьоп х); уу конструктор мо(с( виси (); шус1авя::гпус1аяя(1пс х) ( сопя « "н коаструкторе1о"; уоЫ тпуо1аяя:: янои () ( сош « а « "Ы"; Самоучитель С~-~ (в( зпага (,' кус1аээ оЬ(4); оЬ.аЬои(); текитн О; Здесь конструктор класса (пус1авв имеет один параметр.
Значение, передаваемое в п(ус1авв(), используется для инициализации переменной а. Обратите особое внимание на то, как в функции п(а1п() объявляется объект оЬ. Число 4, записанное в круглых скобках, является аргументом, передаваемым параметру х конструктора тус1ава(), который используется для инициализац и и переменной а. Фактически синтаксис передачи аргумента конструктору с параметром является сокращенной формой записи следующего, более длинного выражения: птус1аза оЬ = ает 1ава(4) Однако большинство программистов С++ пользуются сокращенной формой записи. На самом деле, с технической точки зрения между этими двумя формами записи имеется небольшое отличие, связанное с конструктором копий (сору сопз(гцс(ог), о котором будет рассказано позже. На данном этапе об этом отличии можно не беспокоиться. $4й)вйф~~- / В отличие от конструктора деструктор не может иметь параметров.
Смысл этого понять достаточно просто: отсутствует механизм передачи аргументов удаленному обьекту. (,, Примеры~,: 1. Вполне допустимо передавать конструктору несколько аргументов. В этом примере конструктору игус!авао передается два аргумента: ((гпс1нбе <1оз степа> па(пя патпеьрасе всс(; с1авв тпус!ааа (пг а, Ьр рцЫ1с: тус1авз(гас х, гнт. у); // конструктор чогс( эЬон (); 53 Глава 2. Введение в классы гпус1авв: иаус1авв (1пс х, (пг у) соп1 « "В конструктореМ"; а = х ь-у; .
о1б жус1авв:; в)тон () сош « а « ' ' « Ь « "~п"; [п1 п~агп ( ) гпус1авв оЬ(4, 7) оЬ.в)тон(); гегигп 0; Здесь 4 передается в х, а 7 передается в у. Такой же общий подход используется для передачи любого необходимого числа аргументов (ограниченного, разумеется, возможностями компилятора). 2. Здесь представлена следующая версия класса в1ас(г, в котором конструктор с параметром используется для присвоения стеку "имени". Это одно- символьное имя необходимо для идентификации стека в случае возникновения ошибки. ()1пс1иг(е <1овсгеап~> пв(пя пагпеврасе в(с(; ()с(е51пе 51ХЕ 10 // Объявление класса в1ас1 для символов с1авв вгас)< ( сЬаг всск[Б1ЕЕ); // содержит стек 1п1 1ов; // индекс вершины стека сЬаг в (то; // идентифицирует стек риЬВс: в1ас1(сЬаг с); // конструктор уоЫ рпвЬ(сЬаг сЬ); // помешает в стек символ сЬаг рор () у // выталкивает из стека символ Инициализация стека всас1".: всас1 (сйаг с) ( 1ов= О; В)1О = С; Самоучитель соШ « "Работа конструктора стека '" « ~йо « "'М") Помещение символа в стек чоЫ атас)<::роз)т(с)зал с)т) 1й (~оз==31ЕК) ( сопб « "Стек " « ипо « " полон ~п"~ теСпсп; ) зсск [гоз) с)'; воз++; Выталкивание символа из стека сЬат власам::рор() ( (воз==О) ( сон' « "Стек " « ипо « " пуст тебптп О; !1 возврат нуля при пустом стеке ) соз--; теслтп зГ.с)<[1оз)р 1пс аи1п() ( образование двух автоматически инициализируемых стеков Ясас)< з1 ( а )с 52( в ) (пв 1' з1.раза( 'а'); з2.ризЛ('х']; з1,ризЬ('Ь'); з2,ратай('у')~ з1.ризЬ('с') ) з2.