В каких случаях не будет сгенерирован конструктор копирования?cplus-86

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

Конструктор копирования по умолчанию не будет сгенерирован компилятором автоматически в следующих ситуациях:

1. Пользователь определил свой конструктор копирования

class MyClass {
public:
    MyClass(const MyClass& other) { /* пользовательская реализация */ }
    // Теперь компилятор не сгенерирует конструктор копирования по умолчанию
};

2. Класс содержит не копируемые члены

class NonCopyable {
    std::mutex mtx;  // mutex нельзя копировать
    // Конструктор копирования не будет сгенерирован
};

3. Пользователь определил move-операции

class MoveOnly {
public:
    MoveOnly(MoveOnly&&) noexcept;  // Определен move-конструктор
    // Конструктор копирования не сгенерируется
};

4. Класс имеет члены-ссылки

class RefHolder {
    int& ref;  // Ссылка не может быть перепривязана
    // Конструктор копирования не сгенерируется
};

5. Базовый класс имеет удаленный или недоступный конструктор копирования

class Base {
    Base(const Base&) = delete;
};

class Derived : public Base {
    // Конструктор копирования не сгенерируется
};

6. Виртуальное наследование без явного определения

class VirtualBase {};
class Derived : virtual public VirtualBase {
    // Конструктор копирования не сгенерируется автоматически
};

Особые случаи C++11 и новее

7. Явное удаление конструктора копирования

class NoCopy {
    NoCopy(const NoCopy&) = delete;
};

8. Наличие const-членов, которые нельзя инициализировать

class ConstMember {
    const int value;
    // Конструктор копирования не сгенерируется
};

Последствия отсутствия конструктора копирования

  1. Невозможность копирования объектов класса
  2. Ошибки компиляции при попытке копирования
  3. Ограничения при использовании в контейнерах STL (требуются move-операции)

Как проверить, сгенерирован ли конструктор копирования?

#include <type_traits>

static_assert(std::is_copy_constructible_v<MyClass>, 
              "MyClass should be copy constructible");

Резюмируем

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

  • Пользователь явно определил или удалил его
  • Класс содержит не копируемые члены или ссылки
  • Определены move-операции (C++11+)
  • Базовый класс не копируемый
  • Используется виртуальное наследование
  • Наличие const-членов без инициализации

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