Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Глава 18. Аргументация конструирования 191
Student return } В момент создания объекту типа присваивается собственный идентифи- катор. В данном идентификаторы "раздаются" с помощью глобальной переменной Наш класс Student содержит член id. который является экземпляром класса Stu- dent Конструктор класса Student не может присвоить значение члену по- скольку Student не имеет доступа к защищенным членам класса St.uder.tlD. Можно было бы сделать studen t другом класса но такой подход нарушил бы по- ложение объектно-ориентированного программирования, что каждый класс должен заниматься своим делом. Нам нужна возможность вызывать конструк- тор класса в процессе создания класса C++ делает это автоматически, инициализируя член id с помощью конструктора по умолчанию : StudentiD (). Это происходит после вызова конструктора класса но до того, как управление передается первой строке этого конструкто- ра. (Выполните в пошаговом режиме приведенную выше программу, и вы поймете, о чем я говорю. Только не забудьте при компиляции включить опцию Outline inline func- tions.) Выполнение приведенной выше программы выведет на экран следующие строки: Присваиваем студенту 1 студента Randy Обратите внимание: сообщение от конструктора StudentiD появилось раньше, чем сообщение от конструктора Student. (Поскольку у нас все конструкторы выполняют вывод на экран, вы можете ре- шить, что они всегда должны поступать подобным образом. На самом деле подав- ляющее большинство конструкторов работают "молча".) Если программист не обеспечит свой класс конструктором, то конструктор по умолчанию, созданный C++, вызовет конструкторы всех данных-членов для их ини- циализации. То же касается и уничтожения объекта. Деструктор класса автоматически вызывает деструкторы всех данных-членов (которые, само собой, его имеют). Теперь мы знаем, что будет с конструктором по умолчанию. Но что, если мы захо- тим вызвать другой конструктор? Куда в этом случае нужно поместить объект? Вот что я имею в виду: представьте что вместо автоматической генерации идентифи- катора студента, необходимо передать его конструктору studen t с тем, чтобы он, в свою очередь, передал его конструктору Для начала я покажу вам способ, который работать не будет.
Id {
id = 0) { value = id; << "Присваиваем id, равный " << value << }
{ cout << "Удаляем студента " << value << "\n";
192 Часть III. "Классическое" программирование protected: value
class Student {
= "no name", int = 0) f « "Создаем студента " << pName <<
- 1] = Вот это можно и не пытаться делать / / - толку не будет
} protected: char ; id; }; int argcs, ( 1234); cout « "Сообщение из main\n"; 0; ) Конструктор класса был переписан так, чтобы он мог принимать внешнее значение (значение по умолчанию необходимо для того, чтобы ный фрагмент откомпилировался без ошибок, которые в противном случае появят- ся; почему — станет понятно чуть позже). Внутри конструктора програм- мист (т.е. я) попытался невиданным доселе способом сконструировать объект id класса Если вы внимательно посмотрите на сообщения, которые выдаются в результате работы этой программы, то поймете, в чем проблема, Присваиваем студенту id, равный 0 Создаем студента Randy Присваиваем студенту id, равный 1234 Удаляем студента 1234 Сообщение из Удаляем студента 0 Первая проблема заключается в том, что конструктор класса вызывает- ся дважды: в первый раз с нулем и только затем с ожидаемым числом 1234. Кроме того, объект с идентификатором 1234 ликвидируется перед выводом сообщения от main{). Очевидно, объект класса studentl D ликвидируется внутри конструктора класса Student. Объяснить такое странное поведение программы довольно просто. Член id уже существует к моменту перехода управления к телу конструктора Поэтому вместо инициализации уже существующего члена id объявление в последней строке конструктора вызывает создание локального объекта с таким же именем. Этот локальный объект и уничтожается при выходе из конструктора. Очевидно, нужен некий механизм конструирования не нового объекта, а уже су- ществующего. Этот механизм должен работать перед открытием фигурной скобки конструктора. Для этого в C++ определена следующая конструкция: |
Последнее изменение этой страницы: 2019-04-19; Просмотров: 199; Нарушение авторского права страницы