Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Козак Н.В. Лекции Основы создания программ в Си...doc
Скачиваний:
24
Добавлен:
23.09.2019
Размер:
2.24 Mб
Скачать

Список инициализации элементов

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

Список инициализации следует за заголовком (сигнатурой) определения конструктора после двоеточия и состоит из инициализаторов элементов дан­ных и базовых классов, разделенных запятыми. Каждому элементу списка пе­редается один или несколько параметров, требуемых для инициализации.

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

class Time

{

int hr, min;

public:

Time(int h) { hr = h; min = 0; }

Time (int h, int m):hr(h), min(m)

{}

};

Тело второго конструктора, как видите, пусто.

Конструктор копии

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

class Time

{

int hr, min;

public:

Time(int h, int m) : hr (h), min(m) {}

Time(const Time &src) // Конструктор копии.

{

hr = src.hr;

min = src.min;

} //

};

int main()

{

Time start (17,45); // Вызывается первый конструктор.

Time current = start; // Вызывается конструктор копии,

return 0;

}

Конструктор копии играет в C++ чрезвычайно важную роль. Как мы сказали, он вызывается при инициализации вновь создаваемого представителя класса значениями существующего объекта. Это означает, что он вызывается всякий раз, когда объект (не ссылка на него!) передается в качестве аргумента функции. Соответствующий формальный параметр, как мы уже говорили, — по су­ществу локальная автоматическая переменная функции, инициализируемая переданным аргументом.

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

Операция присваивания

Операция присваивания — это функция класса с именем operator=, кото­рая принимает в качестве своего единственного параметра ссылку или кон­стантную ссылку на объект данного класса. Она вызывается компилятором, когда существующему объекту присваивается другой объект. Если операция присваивания не предусмотрена, компилятор генерирует ее по умолчанию. В этом случае при присваивании будет выполняться поэлементное (как гово­рят, поразрядное) копирование данных объекта.

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

Вот пример класса с операцией присваивания:

class Time

{

int hr, min;

public:

Time(int h, int m) : hr (h), min(m) {}

Time &operator= (const Times); // Операция присваивания.

};

Time STime::operator=(const Time &src)

{

if(&src == this) // Проверка на самоприсваивание,

error( "Self assignment!");

hr = src.hr;

min = src.min;

}

return *this; // Возвращает ссылку на свой объект.

}

int main ()

{

Time start(17,45) ;

Time current(18, 0);

start = current; // Вызывает operator=.

return 0;

}

Здесь, кстати, показан прием проверки на самоприсваивание, позволяю­щей предотвратить присваивание объекта самому себе.

Параметры конструктора копии и операции присваивания могут иметь тип либо имя_класса&, либо const имя_класса&. Последнее предпочтительнее, так как простая ссылка на класс не позволяет копировать константные объекты.