Редактировать. На самом деле, хотя то, что я говорю в своем первом ответе, действительно, это реальная причина.
Вначале был 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
со всем - члены и наследование - общедоступными), которые рассматривались извне, как если бы у них был один конструктор без параметров.
Однако, если вы поместили конструктор в class
или struct
, то вы делали это способом C ++ / OO, а не способом C, и не было необходимости в конструкторе по умолчанию.
Так как это служило сокращением, люди продолжали использовать его, даже если совместимость не была возможна иначе (он использовал другие функции C ++, не в C).
Следовательно, когда появилась Java (основанная на C ++ во многих отношениях), а затем и C # (основанная на C ++ и Java по-разному), они сохранили этот подход, поскольку кодеры уже могут быть использованы.
Страуструп пишет об этом на своем языке программирования C ++ и тем более, уделяя больше внимания «почему» языка в «Проектировании и эволюции C ++» .
=== Оригинальный ответ ===
Допустим, этого не произошло.
Допустим, я не хочу конструктор без параметров, потому что я не могу перевести мой класс в осмысленное состояние без него. Действительно, это то, что может случиться struct
в C # (но если вы не можете осмысленно использовать все нули и нули struct
в C #, вы в лучшем случае используете невидимую для оптимизации оптимизацию, а в противном случае имеете недостаток дизайна в использовании struct
).
Чтобы мой класс мог защитить свои инварианты, мне нужно специальное removeDefaultConstructor
ключевое слово. По крайней мере, мне нужно создать частный конструктор без параметров, чтобы никакой вызывающий код не вызывал значение по умолчанию.
Что еще больше усложняет язык. Лучше не делать этого.
В целом, лучше не думать о добавлении конструктора как об удалении по умолчанию, лучше о том, чтобы вообще не иметь конструктора как синтаксического сахара для добавления конструктора без параметров, который ничего не делает.