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

Void print() {

std::cout << "color: " << m_color << " and radius: " << m_radius << '\n';

}

};

Int main() {

Thing defl;

defl.print();

Thing red("red");

red.print();

Thing thirty(30.0);

thirty.print();

Thing redThirty("red", 30.0);

redThirty.print();

return 0;

}

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

color: blue and radius: 20

color: red and radius: 20

color: blue and radius: 30

color: red and radius: 30

Задание №2

Зачем мы объявили пустой конструктор по умолчанию в программе из задания №1?

Все же переменные-члены и так имеют значения по умолчанию.

Делегирующие конструкторы

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

Проблема

При создании нового объекта класса, компилятор C++ неявно вызывает конструктор этого объекта.

Не редкость встретить класс с несколькими конструкторами, которые частично выполняют одно и то же, например:

class Boo {

public:

Boo() {

// Часть кода X

}

Boo(int value) {

// Часть кода X

// Часть кода Y

}

};

Здесь есть 2 конструктора: конструктор по умолчанию и конструктор, который принимает целочисленное значение.

Поскольку  Часть кода X требуется обоим конструкторам, то она дублируется в каждом из них.

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

Решение в C++11

Неплохо было бы, чтобы конструктор Boo(int)  вызывал конструктор Boo() для выполнения Часть кода X :

class Boo{

public:

Boo() {

// Часть кода X

}

Boo(int value) {

Boo(); // используем конструктор, указанный выше, для выполнения //части кода X

// Часть кода Y

}

};c:

Boo() {

Однако, если ваш компилятор не совместим с C++11, и вы попытаетесь вызвать один конструктор внутри другого конструктора, то это скомпилируется, но будет работать не так, как вы ожидаете.

До C+Использование отдельного метода

Конструкторам разрешено вызывать другие методы класса, которые не являются конструкторами.

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

Лучшим решением будет, например, создание отдельного метода (не конструктора), который будет выполнять общую инициализацию, и оба конструктора будут вызывать этот метод. Например:

class Boo {

private:

Void DoX() {

// Часть кода X

}

public:

Boo() {

DoX();

}

Boo(int nValue) {

DoX();

// Часть кода Y

}

};

Здесь мы свели дублирование кода к минимуму.

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

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

Однако это приведет к неожиданным результатам.

Многие разработчики просто копируют код из конструктора в функцию инициализации — это сработает, но приведет также к дублированию кода.

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

class Boo {

public:

Boo() {