Какова связь между правилом пяти, наследованием и полиморфизмом в C++?
Я изучал деструкторы, конструкторы копирования, конструкторы перемещения и все остальное. Я также узнал рекомендацию о том, чтобы пометить ваш деструктор как виртуальный в базовом классе, от которого унаследованы производные классы.
Согласно правилу пяти, если я определяю деструктор внутри класса, я должен также определить конструктор копирования и оператор присваивания, а также конструктор перемещения и оператор присваивания внутри класса.
Мой вопрос о правиле пяти касается наследования и полиморфизма. Если я создам базовый класс, от которого унаследованы производные классы, будет ли правило пяти применяться только к базовому классу или оно также будет применяться к производным классам?
1 ответ
То, что делает базовый класс (какие специальные члены он настраивает), не влияет на правило 3/5/0 для производного класса. Производный класс должен использовать правило нуля, если ему не нужно настраивать специальные члены для себя.
Обратите внимание, что простое добавление виртуального деструктора считается его настройкой для целей правила 3/5/0, что означает, что вы должны следовать правилу 3/5 для этого класса.
Но причина не очевидна: объявление любого деструктора (не важно, есть он или нет) лишает вас операций перемещения, оставляя только операции копирования. Это молча заменяет все ходы вашего класса копиями, что нехорошо. (Это не влияет на производные классы, они по-прежнему перемещаются, за исключением подобъекта базового класса в них.)
Перемещая операции, чтобы вернуть их обратно, удаляются операции копирования, которые также необходимо редактировать.
Вышеизложенное будет иметь значение только для классов с элементами данных (которые выигрывают от перемещения), но есть еще одна проблема: тот факт, что операции копирования остаются при объявлении деструктора устаревшим, они должны исчезнуть, как это делают операции перемещения.
Это означает, что если у вас есть виртуальный деструктор, вы должны=default
операции копирования и перемещения, даже если у вас нет элементов данных, чтобы избежать предупреждений об устаревании (сборка с-Wdeprecated
чтобы включить их).