Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Лекции 1-2.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
142.98 Кб
Скачать

Копирующая инициализация

Подобно обычным переменным, классы также можно инициализировать, используя копирующую инициализацию:

int a = 7; // копирующая инициализация

Fraction eight = Fraction (8); // копирующая инициализация,

//вызывается Fraction(8, 1)

Fraction nine = 9; // копирующая инициализация. Компилятор будет

//искать пути конвертации 9 в Fraction, что приведет к вызову

//конструктора Fraction(9, 1)

Однако рекомендуется избегать этой формы инициализации классов, так как она может быть менее эффективной.

Хотя uniform-инициализация, прямая и копирующая инициализации работают одинаково с фундаментальными типами данных, с классами это не совсем так (хотя конечный результат часто совпадает).

Правило: Не используйте копирующую инициализацию с объектами ваших классов.

Уменьшение количества конструкторов

В примере с классом Fraction и двумя конструкторами (по умолчанию и с параметрами), конструктор по умолчанию на самом деле лишний.

Мы могли бы упростить этот класс следующим образом:

#include <cassert>

class Fraction {

private:

int m_numerator;

int m_denominator;

public:

// Конструктор c умалчиваемыми значениями

Fraction (int numerator=0, int denominator=1) {

assert (denominator != 0);

m_numerator = numerator;

m_denominator = denominator;

}

int getNumerator () {return m_numerator;}

int getDenominator () {return m_denominator;}

double getValue () {return static_cast<double>(m_numerator) / m_denominator;}

};

Хотя этот конструктор по-прежнему является конструктором по умолчанию, он теперь определен таким образом, что может принимать одно или два значения, предоставленные пользователем:

Fraction drob; // вызов Fraction(0, 1)

Fraction seven(7); // вызов Fraction(7, 1)

Fraction sixTwo(6, 2); // вызов Fraction(6, 2)

На практике старайтесь сокращать количество конструкторов вашего класса.

Неявно генерируемый конструктор по умолчанию

Если ваш класс не имеет конструкторов, то язык C++ автоматически сгенерирует для вашего класса открытый конструктор по умолчанию.

Его иногда называют неявным конструктором 

(или «неявно сгенерированным конструктором»).

Рассмотрим следующий класс:

class Date {

private:

int m_day = 12;

int m_month = 1;

int m_year = 2018;

};

У этого класса нет конструктора, поэтому компилятор сгенерирует следующий конструктор:

class Date {

private:

int m_day = 12;

int m_month = 1;

int m_year = 2018;

public:

Date () // неявно генерируемый конструктор

{ }

};

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

Хотя вы не можете увидеть неявно сгенерированный конструктор, но его существование можно доказать:

class Date {

private:

int m_day = 12;

int m_month = 1;

int m_year = 2018;

// Не было предоставлено конструктора, поэтому C++ автоматически //создаст открытый конструктор по умолчанию

};