Правило нуля в C - вільний C
Тепер, коли ми зрозуміли згенеровані компілятором функції, правило трьох і правило п’ять, давайте використаємо це, щоб задуматися про те, як використовувати функцію “= за замовчуванням”, щоб мати виразний і правильний код.

Справді, C ++ 11 додав можливість вимагати від компілятора написання реалізації за замовчуванням для цих методів класу:
Але компілятор може також генерувати ці функції, навіть якщо ми не вказуємо їх в інтерфейсі. Ми побачили, що ця функція С ++ мала деякі хитросплетіння, але у наведеному вище випадку, код цілком еквівалентний цьому:
Це піднімає питання: якщо компілятор може надати реалізацію за замовчуванням, чи слід писати = default, щоб бути більш явним, навіть коли це не змінює сформований код? Або це безоплатна багатослівність? Який шлях виразніший?
У нас були дебати з моїми колегами (підказка їм), я розкопався, зрозумівши, що це була гаряча дискусія: Основні рекомендації C ++ мають свою думку, Скотт Мейерс - свою думку, і вони насправді не погоджуються між собою. Подивимось, про що це все.
Основні рекомендації C ++ та Р. Мартіньо Фернандес: Правило нуля
Основні вказівки C ++ дуже чітко розглядають це питання, а початкові вказівки щодо конструкторів зазначають:
C.20: Якщо ви можете уникнути визначення операцій за замовчуванням, зробіть.
Правильно. Досить чітко. Тепер, в чому полягає обгрунтування цього керівного принципу?
Причина Це найпростіший і дає найчистішу семантику. [Якщо всі члени] мають усі спеціальні функції, подальша робота не потрібна.
І далі керівництво говорить, що це відоме як “Правило нуля“.
Цей термін був придуманий Р. Мартіньо Фернандесом у дописі в блозі 2012 року (дякую Lopo та Reddit користувачеві сфера991 за розкопування допису).
Що таке правило нуля? Це виглядає так: Класи, які оголошують власні деструктори, конструктори копіювання/переміщення або оператори призначення копіювання/переміщення, повинні мати справу виключно з правом власності. Інші класи не повинні оголошувати власні деструктори, конструктори копіювання/переміщення або оператори призначення копіювання/переміщення (Правило Нуля злегка перефразоване Скоттом Майерсом).
Згідно з Правилом нуля, є два варіанти щодо функцій, які компілятор може генерувати: або всі вони мають нетривіальну реалізацію, що стосується права власності, або жоден з них не оголошений.
За винятком того, що якщо ви уважно його розглянете, Правило Нуля нічого не говорить про конструктор за замовчуванням X (). У ньому згадуються лише 5 функцій, які в іншому випадку беруть участь у Правилі п’яти. Нагадаємо, «Правило п’яти» говорить, що якщо одна з 5 функцій управління ресурсами (конструктори копіювання/переміщення, оператори присвоєння копій/переміщень, деструктор) мала нетривіальну реалізацію, то інші, безумовно, повинні мати нетривіальну реалізацію теж.
То як щодо конструктора за замовчуванням? Якщо його реалізація є тривіальною, чи слід оголошувати це з = default або взагалі не оголошувати, і нехай компілятор виконує цю роботу?
Але основна настанова C ++ C.20, схоже, заохочує нас також не заявляти про це:
C.20: Якщо ви можете уникнути визначення операцій за замовчуванням, зробіть.
Все ще досить чітко.
Скотт Майерс: Правило п’яти дефолтів
Скотт Мейєрс у відповідь на "Правило нуля" пише, що це становить ризик.
Дійсно, декларування будь-якої з 5 функцій має побічний ефект на автоматичну генерацію операцій переміщення. Досить суворий побічний ефект, оскільки він вимикає автоматичну генерацію операцій переміщення. (Якщо вам цікаво, навіщо саме операції переміщення, подивіться на оновлення функцій, створених компілятором, Правила трьох і Правила П’яти).
Зокрема, якщо ви додаєте деструктор до класу:
Потім він втрачає свої операції переміщення. АЛЕ він не втрачає копіювальних операцій! Отже, клієнтський код буде продовжувати компілювати, але буде мовчки викликати копію замість переміщення. Це не добре.