double arrow

Автоматическая инициализация


Когда создается объект типа Counter, нам хотелось бы, чтобы его поле count было инициализировано нулевым значением, поскольку большинство счетчиков на­чинают отсчет именно с нуля. Мы могли бы провести инициализацию с помо­щью вызова функции set_count() с аргументом, равным нулю, или создать специ­альный метод zero_count(), обнуляющий значение функции. Недостаток такого подхода заключается в том, что эти функции необходимо вызывать явно каждый раз при создании объекта типа Counter:

Counter cl: // при определении объекта

cl.zero_count():   // это необходимое действие

Подобные действия легко могут привести к неправильной работе всей про­граммы, поскольку программисту для этого достаточно забыть проинициализировать хотя бы одну переменную после ее создания. Если в программе создается множество таких переменных, гораздо проще и надежнее было бы инициализи­ровать их автоматически при создании. В нашем примере конструктор Counter() выполняет эти действия. Конструктор вызывается автоматически при создании каждого из объектов. Таким образом, в функции mainQ оператор

Counter cl. с2:

создает два объекта типа Counter. При создании каждого из них вызывается конст­руктор Counter(), присваивающий полю counter нулевое значение. Таким образом, кроме создания переменных, данный оператор еще присваивает их полям нулевое значение.




Инициализаторы в конструкторах

Главной задачей конструктора класса является инициализация данных созда­ваемых им объектов. Однако производить инициализацию данных при по­мощи оператора присваивания в теле конструктора не рекомендуется.

Инициализация осуществляется при помощи списка инициализации, распо­ложенного между двоеточием, которое следует за закрывающей круглой скобкой в заголовке конструктора, и телом конструктора. Присваиваемые при инициализации данных значения записываются в круглых скобках после идентификаторов членов-данных и отделяются друг от друга запятыми.

Порядок следования идентификаторов в списке инициализации не имеет зна­чения.

Для каждого объекта класса Counter конструктор выполняет инициализацию поля count нулем. Вы, вероятно, ожидали, что это действие будет произведено в теле конструктора приблизительно следующим образом:

count()

{ count =0; }

Такая форма записи не рекомендуется, несмотря на то, что она не содержит ошибок. Инициализация в нашем примере происходит следующим образом:

count(): count(0)

{ }

Инициализация расположена между прототипом метода и телом функции и предварена двоеточием. Инициализирующее значение помещено в скобках пос­ле имени поля.

Если необходимо инициализировать сразу несколько полей класса, то значе­ния разделяются запятыми, и в результате образуется список инициализации:



someClass () : m1(7), m2(33), m2(4) { }

Результаты работы программы со счетчиком

В функции main() рассматриваемой нами программы создаются два объекта класса Counter с именами cl и с2. Затем на экран выводятся значения полей каж­дого из объектов, которые, согласно нашей задумке, должны быть инициализи­рованы нулевыми значениями. Далее значение счетчика cl инкрементируется один раз, а значение счетчика с2 — два раза, и программа вновь заставляет объек­ты вывести значения своих полей на экран (что является в данном случае вполне корректным). Результат работы программы выглядит следующим образом:

cl=0

с2=0

cl=1

с2=2

Для того чтобы убедиться в том, что конструктор функционирует именно так, как мы описали выше, заставим его печатать сообщение во время выполнения:

counter() : count(0)

{ cout << "Конструктор\n": }

Теперь результат работы программы будет выглядеть следующим образом:

Конструктор

Конструктор

cl=0

с2=0

cl=1

с2=2

Как можно видеть, конструктор исполняется дважды: первый раз — для переменной cl, второй раз — для переменной с2, во время выполнения оператора

counter cl, с2; в функции main().

 

Конструктор по умолчанию

Конструктор по умолчанию — конструктор, не требующий параметров. Этот конструктор всегда должен быть определен для любого класса. Конструктор по умолчанию может не выполнять никаких действий, но чаще всего он ини­циализирует данные класса нулевыми значениями.

Объявление конструктора по умолчанию имеет следующий формат:



public:имя_класса ( ) ;

Например, для класса своок прототип конструктора по умолчанию записыва­ется со спецификатором открытого доступа

public: CBook ( ) ;

 

Пример реализации конструктора по умолчанию ]

СВоок : : СВоок ( ) : m_year ( 0 ) , m_pTitle ( "" )

{      m_author [ 0 ] = ‘\0' ;    }

 

В результате работы этого конструктора будет построен объект-книга, у которого данное year получит нулевое значение, массив author нач­нется с нулевого байта точно так же, как и название книги, на которое указы­вает pTitie. Для инициализации автора не может быть использован инициа­лизатор, так как этот член-данное объявлен в классе как символьный массив.

 

Конструктор с параметрами

Конструктор с параметрами инициализирует значения данных объекта зна­чениями полученных параметров. Параметров будет столько, сколько данных необходимо проинициализировать. Прототип такого конструктора имеет формат:

public:имя_класса ( список формальных параметров ) ;

Для класса CBook конструктор с параметрами может иметь следующий прото­тип: CBook ( char*, char*, int ) ;

 

Пример реализации конструктора с параметрами

СВоок :: СВоок ( char *author, char *title, int year )

: m_уеаг ( year ), m_pTitle ( title )

{

strncpy_s ( m_author, 50, author, 49 ) ;

if ( strlen ( author ) > 49 ) m_author [ 49 ] = '\0' ;

}

 

В результате работы этого конструктора будет построен объект-книга, у которого данное щ_уеаг получит значение параметра year, в массив m_author будет скопировано не более 49 байтов из строки author, и указатель m_pTitie будет содержать адрес, по которому скопировано значение title.







Сейчас читают про: