Правило трех (программирование на C++)
Правило трех и правило пяти — это практические правила в C++ для создания кода, защищенного от исключений , и для формализации правил управления ресурсами . Правила предписывают, как члены класса следует использовать по умолчанию для систематического достижения этих целей.
Правило трех
[ редактировать ]Правило трех (также известное как закон большой тройки или большой тройки ) — это эмпирическое правило в C++ (до C++11 ), которое утверждает, что если класс определяет что-либо из следующего, то, вероятно, его следует явно указать. определить все три: [ 1 ]
Эти три функции являются специальными функциями-членами . Если одна из этих функций используется без предварительного объявления программистом, она будет неявно реализована компилятором со следующей семантикой по умолчанию:
- Деструктор – вызов деструкторов всех членов типа класса объекта.
- Конструктор копирования — создает все члены объекта из соответствующих членов аргумента конструктора копирования, вызывая конструкторы копирования членов типа класса объекта и выполняя простое присвоение всех членов данных неклассового типа (например, int или указатель).
- Оператор копирования присваивания — присваивание всех членов объекта из соответствующих членов аргумента оператора присваивания, вызов операторов копирования членов типа класса объекта и выполнение простого присваивания всех данных неклассового типа (например, int или указатель). члены.
Правило трех утверждает, что если один из них должен быть определен программистом, это означает, что сгенерированная компилятором версия не соответствует потребностям класса в одном случае и, вероятно, не подойдет и в других случаях. Термин «Правило трёх» был придуман Маршаллом Клайном в 1991 году. [ 2 ]
Поправка к этому правилу заключается в том, что если класс спроектирован таким образом, что для всех его (нетривиальных) членов используется инициализация получения ресурсов (RAII), деструктор можно оставить неопределенным (также известный как «Закон большой двойки»). [ 3 ] ). Готовый пример такого подхода — использование интеллектуальных указателей вместо простых. [ 3 ]
Поскольку неявно сгенерированные конструкторы и операторы присваивания просто копируют все элементы данных класса (« мелкое копирование »), [ 4 ] следует определить явные конструкторы копирования и операторы присваивания копирования для классов, которые инкапсулируют сложные структуры данных или имеют внешние ссылки, такие как указатели, если вам нужно скопировать объекты, на которые указывают члены класса. Если поведение по умолчанию («мелкая копия») на самом деле является предполагаемым, то явное определение, хотя и избыточное, будет « самодокументируемым кодом », указывающим, что это было намерением, а не недосмотром. Современный C++ включает синтаксис , позволяющий явно указать, что требуется функция по умолчанию, без необходимости вводить тело функции.
Правило пяти
[ редактировать ]С появлением C++11 правило трёх может быть расширено до правила пяти (также известного как «правило большой пятёрки»). [ 5 ] ), поскольку C++11 реализует семантику перемещения , [ 6 ] позволяя объектам назначения захватывать (или красть ) данные из временных объектов. В следующем примере также показаны новые перемещаемые члены: конструктор перемещения и оператор присваивания перемещения. Следовательно, для правила пяти у нас есть следующие специальные члены :
- деструктор
- конструктор копирования
- копировать оператор присваивания
- переместить конструктор
- переместить оператор присваивания
Существуют ситуации, когда классам могут потребоваться деструкторы, но они не могут разумно реализовать конструкторы копирования и перемещения, а также операторы копирования и перемещения присваивания. Это происходит, например, когда базовый класс не поддерживает последних членов Большой четверки , но конструктор производного класса выделяет память для собственного использования. [ нужна ссылка ] В C++11 это можно упростить, явно указав пять членов по умолчанию. [ 7 ]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Страуструп, Бьярне (2000). Язык программирования C ++ (3-е изд.). Аддисон-Уэсли. стр. 283–4 . ISBN 978-0-201-70073-2 .
- ^ Кениг, Эндрю; Барбара Э. Му (1 июня 2001 г.). «С++ стал проще: правило трех» . Журнал доктора Добба . Проверено 8 сентября 2009 г.
- ^ Перейти обратно: а б Карлссон, Бьёрн; Уилсон, Мэтью (1 октября 2004 г.). «Закон большой двойки» . Исходный код С++ . Артима . Проверено 22 января 2008 г.
- ^ Язык программирования C++ . п. 271.
- ^ «C++11: Правило большой пятерки» (PDF) . Проверено 4 июня 2018 г.
- ^ Страуструп, Бьярне (7 апреля 2013 г.). «C++11 — новый стандарт ISO C++» . Проверено 10 мая 2013 г.
- ^ «Правило трёх/пяти/ноля» . cppreference.com . Проверено 15 февраля 2015 г.