Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора к КПИЯП.docx
Скачиваний:
41
Добавлен:
25.02.2016
Размер:
135.65 Кб
Скачать

2.3 Конструкторы и деструкторы

 

Существуют два способа определения целочисленной переменной. Можно сначала определить переменную, а затем (несколько ниже в программе) присвоить ей значение, например:

 int Weight;           // определить переменную

 Weight =7;           // присвоить переменной значение

 Или, определив переменную, можно сразу инициализировать ее, например:

 int Weight =7;      // определить и инициализировать значением 7

 Инициализация сочетает в себе определение переменной с присвоением ей начального значения. Причем ничто не мешает впоследствии изменить это значение. Кроме того, инициализация гарантирует, что переменная не останется без начального значения и не будет содержать мусор, оставшийся в выделенном ей участке памяти.

Как же инициализировать переменные-члены класса? Для этого в классе используется специальная функция-член, называемая конструктором (constructor). При необходимости конструктор может получать параметры, но не может возвращать значения, даже типа voidКонструктор — это метод класса, имя которого совпадает с именем самого класса.

Объявив конструктор, необходимо объявить и деструкторЕсли конструкторы служат для создания и инициализации объектов класса, то деструкторы удаляют из памяти отработавшие объекты и освобождают выделенную для них памятьДеструктору всегда присваивается имя класса с символом тильды (~) в начале.Деструкторы не принимают аргументы и не возвращают значения. Объявление деструктора класса Cat будет выглядеть следующим образом: ~Cat();

 

Стандартные конструкторы и деструкторы

 

Доступны несколько типов конструкторов, одним из них передают параметры, другим — нет. Те, которые не получают аргументов, называются стандартными (default)Однако деструктор может быть только один. Никакие аргументы он не принимает.

Кроме того, если конструктор или деструктор не созданы явно, компилятор создаст их сам. Конструктор, созданный компилятором, будет стандартным, т.е. без аргументов. Но можно создать и собственный стандартный конструктор.

Созданные компилятором конструктор и деструктор не только не имеют аргументов, но и ничего не делают! Если в конструкторе следует осуществить какие либо действия, необходимо создать свой собственный стандартный конструктор или деструктор.

 

Использование стандартного конструктора

 

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

 

Например:

Cat Rags; // Rags не получает никаких параметров

Его конструктор будет иметь вид: Cat();

 

Вызов конструктора происходит при создании объекта класса. Если для создания объекта класса Cat следует передать два параметра, то его определение будет выглядеть следующим образом: Cat Frisky (5,7);

Первым параметром в этом примере мог бы быть возраст кота, а вторым — его вес. Если конструктор принимает один параметр, то определение объекта будет иметь вид: Cat Frisky (3);

Когда конструктор вообще не принимает параметров (т.е. является стандартным), отпадает необходимость в круглых скобках. Cat Frisky;

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

Cat Frisky;

Эта запись интерпретируется как обращение к стандартному конструктору. В ней отсутствует передача параметров и, следовательно, круглые скобки.

Кстати, использовать предоставляемый компилятором стандартный конструктор вовсе не обязательно. Вполне возможно написать собственный стандартный конструктор, т.е. конструктор без параметров. В разделе реализации стандартного конструктора можно выполнить инициализацию объекта класса.

Чтобы придать классу законченность, при объявлении конструктора не забудьте объявить и деструктор, даже если ему нечего делать. Хотя и стандартный деструктор будет работать корректно, отнюдь не повредит объявить собственный. Это сделает программу более ясной.

В листинге 16.1 класс Cat дополнен конструктором и деструктором. Конструктор используется для инициализации объекта класса Cat и установки его возраста равным предоставляемому значению. Обратите внимание на место расположения вызова деструктора в коде программы.

 

Листинг 16.1. Использование конструкторов и деструкторов

#include <iostream>

class Cat {                // начало объявления класса

public:                      // начало раздела public

Cat(int initialAge);         // конструктор

~Cat();                 // деструктор

 int GetAge();               // функция доступа

void SetAge(int age);   // функция доступа

void Meow();     

private:

int itsAge;             // переменные-члены

} ;

 

// Конструктор класса Cat

Cat::Cat(int initialAge)

{

itsAge = initialAge;

}

 

// Деструктор класса Cat

Cat: :~Cat ()

{

}

 

// GetAge(), открытая функция доступа, возвращающая значение элемента itsAge

int Cat::GetAge()

{

return itsAge;

}

 

// Реализация открытой функции доступа SetAge(), устанавливающей значение элемента itsAge

void Cat::SetAge(int age)

{

// присвоить переменной-члену itsAge значение, переданное через параметр age

 itsAge = age;

}

 

// Реализация метода Meow()

// Возвращает: ничего (void)

// Параметры: нет

// Действия: выводит на экран "Мяу" (Meow)

void Cat::Meow()

{

std::сout << "Meow.\n";

}

 

// Создать кота, установить его возраст, мяукнуть, сообщить его возраст, а затем мяукнуть снова.

int main()

{

Cat Frisky(5);

Frisky.Meow();

std::cout << "Frisky is a cat who is “;

     std::cout << Frisky.GetAge() << " years old.\n";

Frisky.Meow();

Frisky.SetAge(7);

std::cout << "Now Frisky is ";

     std::cout << Frisky.GetAge() << " years old.\n";

return 0;

}

Результат

Meow.

Frisky is a cat who is 5 years old.

Meow.

Now Frisky is 7 years old. 

Анализ 

В строке 10 объявлен деструктор, который никаких параметров не получает. Помните, что деструкторы никогда не получают параметров; кроме того, ни конструкторы, ни деструкторы не возвращают значения, даже типа void.

В строках 19—22 содержится реализация конструктора, аналогичная реализации функции доступа SetAge (), которая также не возвращает никакое значение. Как можно заметить, имя класса предшествует имени конструктора. Ранее уже было сказано, что таким образом метод Cat() в данном случае объявляется как часть класса Cat. Это конструктор, а, следовательно, он не возвращает никакое значение, даже void. Однако данному конструктору передается начальное значение, которое присваивается переменной-члену itsAge в строке 21.

В строках 24-26 находится реализация деструктора ~Cat (). Сейчас эта функция не делает ничего, но, коль она объявлена в классе, нужно включить и ее реализацию. Подобно конструктору и другим методам, ему также предшествует имя класса. Подобно конструктору, но в отличие от других методов, он никогда не возвращает никакие значения. Это обычное поведение деструктора.

В строке 57 создается объект Frisky класса Cat. В конструктор объекта Frisky передается значение 5. В данном случае нет необходимости вызывать функцию-член SetAge(), поскольку объект Frisky сразу создается со значением 5, присвоенном переменной-члену itsAge, как показано в строке 60. В строке 62 переменной itsAge объекта Frisky присваивается значение 7, на этот раз с помощью функции SetAge (). Новое значение выводится на экран в строке 64.