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

Список инициализации членов класса

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

1. Списки инициализации членов класса

2. uniform-инициализация в C++11

3. Инициализация массивов в классе

4. Инициализация переменных-членов, которые являются классами

5. Использование списков инициализации

6. Порядок выполнения в списке инициализации

7. Заключение

Списки инициализации членов класса

Мы инициализировали члены нашего класса в конструкторе 

через оператор присваивания:

class Values {

private:

Int m_value1;

double m_value2;

char m_value3;

public:

Values() {

// Это всё операции присваивания, а не инициализация

m_value1 = 3;

m_value2 = 4.5;

m_value3 = 'd';

}

};

Сначала создаются m_value1, m_value2 и m_value3. Затем выполняется тело конструктора, где этим переменным присваиваются значения. Аналогичен код в не объектно-ориентированном C++:

Int m_value1;

double m_value2;

char m_value3;

m_value1 = 3;

m_value2 = 4.5;

m_value3 = 'd';

Хотя в плане синтаксиса языка C++ вопросов никаких нет — всё корректно, но более эффективно — использовать инициализацию, а не присваивание после объявления.

Для решения этой проблемы в C++ добавили метод инициализации переменных-членов класса через список инициализации членов, вместо присваивания им значений после объявления.

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

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

double value2(4.5); // прямая инициализация

char value3 {'d'} // uniform-инициализация

Использование списка инициализации почти идентично выполнению прямой инициализации (или uniform-инициализации).

Чтобы было понятнее, рассмотрим пример. Вот код с присваиванием значений переменным-членам класса в конструкторе:

class Values {

private:

int m_value1;

double m_value2;

char m_value3;

public:

Values() {

// Это всё операции присваивания, а не инициализация

m_value1 = 3;

m_value2 = 4.5;

m_value3 = 'd';

}

};

Теперь давайте перепишем этот код, но уже с использованием списка инициализации:

#include <iostream>

class Values {

private:

int m_value1;

double m_value2;

char m_value3;

public:

Values() : m_value1(3), m_value2(4.5), m_value3('d') // напрямую //инициализируем переменные-члены класса

{ // Нет необходимости использовать присваивание }

void print() {

std::cout << "Values(" << m_value1 << ", " << m_value2 << ", " << m_value3 << ")\n";

}

};

int main() {

Values value;

value.print();

return 0;

}

Результат выполнения программы:

Values(3, 4.5, d)

Список инициализации членов находится сразу же после параметров конструктора.

Он начинается с двоеточия (:), а затем значение для каждой переменной указывается в круглых скобках. Больше не нужно выполнять операции присваивания в теле конструктора.

Также обратите внимание, что список инициализации членов не заканчивается точкой с запятой.

Можно также добавить возможность передавать значения в конструктор для инициализации:

#include <iostream>

class Values {

private:

int m_value1;

double m_value2;

char m_value3;

public:

Values(int value1, double value2, char value3='d')

: m_value1(value1), m_value2(value2), m_value3(value3)

// напрямую инициализируем переменные-члены класса

{ // Нет необходимости использовать присваивание }

void print() {

std::cout << "Values(" << m_value1 << ", " << m_value2 << ", " << m_value3 << ")\n";

}

};

int main() {

Values value(3, 4.5); // value1 = 3, value2 = 4.5, value3 = 'd' (значение

// по умолчанию)

value.print();

return 0;

}

Результат выполнения программы:

Values(3, 4.5, d)

Мы можем использовать параметры по умолчанию для предоставления значений по умолчанию.

Например, класс, который имеет константную переменную-член:

class Values {

private:

const int m_value;

public:

Values(): m_value(7) // напрямую инициализируем константную

// переменную-член

{ }

};

Это работает, поскольку нам разрешено инициализировать константные переменные (но не присваивать им значения после объявления!).

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

uniform-инициализация в C++11

В C++11 вместо прямой инициализации можно использовать uniform-инициализацию:

class Values {

private:

const int m_value;

public:

Values(): m_value { 7 } // используем uniform-инициализацию

{ }

};

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

Правило: Используйте uniform-инициализацию вместо прямой инициализации в C++11.