Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Глава 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; Просмотров: 177; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.01 с.)
Главная | Случайная страница | Обратная связь