Среди `dctor, copy ctor и copy assignment operator`, почему удаляет один и оставляет неявно определенным другое, скорее всего, приведет к ошибкам - PullRequest
0 голосов
/ 30 мая 2020

Согласно документации (https://en.cppreference.com/w/cpp/language/rule_of_three), в которой говорится:

Классы, которые управляют некопируемыми ресурсами через копируемые дескрипторы, возможно, должны будут объявить назначение копии и конструктор копирования закрытые и не предоставляют их определения и не определяют их как удаленные. Это еще одно применение правила трех: удаление одного и неявное определение другого, скорее всего, приведет к ошибкам.

Как субъект, мне интересно, почему это происходит. это поподробнее? Может ли кто-нибудь прояснить это, приведя простой пример?

1 Ответ

1 голос
/ 30 мая 2020

Ответ находится в предыдущем абзаце:

Неявно определенные специальные функции-члены обычно неверны, если класс управляет ресурсом, дескриптор которого является объектом неклассового типа (необработанный указатель , Дескриптор файла POSIX, et c), деструктор которого ничего не делает, а оператор конструктора / присваивания копирования выполняет «неглубокую копию» (копирование значения дескриптора без дублирования базового ресурса).

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

A Класс, который управляет некопируемым ресурсом, обычно является классом, которому принадлежит какой-то трудно копируемый ресурс. Например, std::filebuf, который управляет файлом (используется std::fstream). Он не определяет ни конструктор копирования, ни оператор присваивания копии: оба удаляются. Он явно определяет деструктор для закрытия файла.

Теперь, если бы деструктор оставался неявно определенным, файл никогда не закрывался бы, а буфер оставался бы в памяти, вызывая утечку памяти. Если конструктор копирования оператора присваивания копии был определен неявно, он скопировал бы указатель на буфер, а затем деструктор потенциально мог бы вызываться несколько раз для одного и того же файла, пытаясь удалить один и тот же буфер несколько раз (что является неопределенное поведение).

...