Что такое конструктор по умолчанию? Для чего нужны default и delete?cplus-89

Конструктор по умолчанию

Конструктор по умолчанию — это конструктор, который может быть вызван без аргументов. Он может быть:

  1. Неявно объявленным (генерируется компилятором автоматически)
  2. Явно определенным программистом
  3. Удаленным (с помощью = delete)

Примеры:

class ImplicitDefault {
    // Компилятор сгенерирует конструктор по умолчанию
};

class ExplicitDefault {
public:
    ExplicitDefault() {}  // Явное определение
};

class DeletedDefault {
public:
    DeletedDefault() = delete;  // Явное удаление
};

Когда компилятор генерирует конструктор по умолчанию

Компилятор автоматически генерирует конструктор по умолчанию, если:

  • Нет других пользовательских конструкторов
  • Все члены класса имеют конструкторы по умолчанию
  • Базовые классы имеют конструкторы по умолчанию
  • Нет виртуальных функций или виртуального наследования

Модификатор = default

Позволяет явно указать компилятору сгенерировать реализацию по умолчанию:

class Widget {
public:
    Widget() = default;  // Явное указание использовать реализацию по умолчанию
};

Преимущества = default:

  1. Делает намерения явными
  2. Позволяет сохранить тривиальность типа
  3. Может использоваться вне класса (в заголовочном файле)

Модификатор = delete

Явно запрещает использование определенных функций:

class NonCopyable {
public:
    NonCopyable(const NonCopyable&) = delete;  // Запрет копирования
};

Применение = delete:

  1. Запрет нежелательных операций (копирования, преобразований)
  2. Удаление специализаций шаблонов
  3. Запрет нежелательных преобразований типов

Практические примеры

1. Создание только move-объекта

class MoveOnly {
public:
    MoveOnly() = default;
    MoveOnly(const MoveOnly&) = delete;
    MoveOnly(MoveOnly&&) = default;
};

2. Запрет нежелательных преобразований

void process(int x);
void process(double) = delete;  // Запрещаем вызов с double

3. Специализация шаблонов

template<typename T>
void log(T value);

template<>
void log<void>(void) = delete;  // Запрещаем вызов с void

Резюмируем

  1. Конструктор по умолчанию — конструктор без параметров, генерируемый компилятором или определяемый явно
  2. = default — явное указание использовать реализацию по умолчанию, сохраняет тривиальность типа
  3. = delete — мощный инструмент для:
    • Запрета копирования/присваивания
    • Удаления нежелательных преобразований
    • Специализации шаблонов

Использование default и delete делает код более выразительным и безопасным, явно документируя намерения разработчика.