Редагувати. Насправді, хоча те, що я кажу в першій своїй відповіді, справедливо, це справжня причина:
На початку був C. C не об'єктно-орієнтований (ви можете скористатися підходом до ОО, але він вам не допомагає і не застосовує нічого).
Потім був C With Classes, який згодом був перейменований на C ++. C ++ є об'єктно-орієнтованим, а тому заохочує інкапсуляцію та забезпечення інваріантності об'єкта - після побудови та на початку та в кінці будь-якого методу об'єкт знаходиться у дійсному стані.
Природно, що для цього потрібно - це встановити, що клас повинен завжди мати конструктор, щоб переконатися, що він запускається у дійсному стані - якщо конструктору не потрібно нічого робити для цього, тоді порожній конструктор задокументує цей факт .
Але мета C ++ повинна була бути сумісною з C настільки, наскільки це можливо, всі дійсні програми C також були дійсними програмами C ++ (більше не як активна мета, а еволюція C окремо до C ++ означає, що вона більше не вдається ).
Одним із наслідків цього було дублювання функціональності між struct
та class
. Перші роблять речі способом C (усе публічно за замовчуванням), а другі роблять речі в хорошому OO (усе приватне за замовчуванням, розробник активно оприлюднює те, що хоче).
Інша полягає в тому, що для того, щоб C struct
, який не міг мати конструктор, оскільки C не має конструкторів, був дійсним у C ++, тоді це повинно було мати сенс для C ++ способу його погляду. І тому, не маючи конструктора протидіяти практиці ОО активного забезпечення інваріанта, C ++ вважає, що існує конструктор без параметрів за замовчуванням, який діяв так, ніби він мав порожнє тіло.
Всі C structs
тепер були дійсними C ++ structs
(що означало, що вони такі самі, як C ++ classes
з усіма - членами та спадщиною - громадськими), які розглядаються ззовні так, ніби вони мають єдиний безпараметричний конструктор.
Якщо ви все-таки поставили конструктор в a class
або struct
, то ви робили речі C ++ / OO, а не C, і не було потреби в конструкторі за замовчуванням.
Оскільки він слугував як скорочення, люди продовжували використовувати його навіть тоді, коли сумісність була неможлива в іншому випадку (він використовував інші функції C ++, які не знаходяться в C).
Отже, коли з'явилася Java (заснована на C ++ у багатьох відношеннях) і пізніше C # (заснована на C ++ та Java по-різному), вони дотримувались такого підходу, як до чогось уже можуть бути використані кодери.
Про це пише Stroustrup у своїй мові програмування на C ++, а ще більше, приділяючи більше уваги "whys" мови в "Дизайні та еволюції C ++" .
=== Оригінальний відповідь ===
Скажімо, цього не сталося.
Скажімо, я не хочу конструктора без параметрів, тому що я не можу перевести свій клас у значущий стан без одного. Дійсно, це може статися з struct
C # (але якщо ви не можете змістовно використовувати цілі нулі та нулі struct
в C #, ви в кращому випадку використовуєте оптимізацію, яка не є загальнодоступною, і в іншому випадку матимете недолік дизайну у використанні struct
).
Щоб мій клас міг захистити своїх інваріантів, мені потрібно спеціальне removeDefaultConstructor
ключове слово. Як мінімум, мені потрібно створити приватний конструктор без параметрів, щоб переконатися, що жоден викликовий код не закликає за замовчуванням.
Що ще більше ускладнює мову. Краще не робити цього.
Загалом, краще не думати про додавання конструктора як видалення за замовчуванням, краще думати про відсутність конструктора як синтаксичний цукор для додавання конструктора без параметрів, який нічого не робить.