Сначала несколько форм Бэкуса-Наура.
Объявление ::= ОбъявлениеФункции
::= ОпределениеФункции
::= *****
ОбъявлениеФункции ::= [СписокСпецификаторовОбъявления] Описатель
[СпецификацияИсключения];
ОпределениеФункции ::= [СписокСпецификаторовОбъявления] Описатель
[ctorИнициализатор] [СпецификацияИсключения] ТелоФункции
Описатель ::= Описатель ([СписокОбъявленийПараметров]) ::= dИмя
dИмя ::= ИмяКласса
Используя это множество БНФ, можно строить объявления весьма странного вида:
ОбъявлениеФункции ::= Описатель; ::= Описатель (); ::= dИмя (); ::= ComplexType ();
Объявление… без спецификатора объявления.
ОпределениеФункции ::= Описатель ТелоФункции ::= Описатель () {} ::= dИмя () {} ::= ComplexType () {}
А это определение. Оно построено в соответствии с правилами построения функций. Не важно, что у него в теле нет ни одного оператора! Важно, что у него нет спецификатора объявления.
Именно так и выглядит конструктор, альтернативный тому, который строится транслятором без участия программиста. Множество операторов (возможно пустое), оформленное в виде блока, с заголовком специального вида (ни слова о возвращаемых значениях) - нечто подобное функции-члену. Подобным образом организованная и весьма напоминающая своим синтаксисом обыкновенную функцию последовательность операторов и отвечает за создание объектов данного класса.
Отметим одно очень важное обстоятельство. Имя конструктора всегда совпадает с именем класса, членом которого является объявляемый конструктор. Ни одна функция-член класса не может называться именем класса. Ни одна функция-член класса не может быть объявлена и определена без спецификатора объявления. Характерное имя и отсутствие спецификации объявления отличает конструктор от функций-членов класса.
Отсутствие спецификаторов объявления означает, что конструктор не имеет абсолютно никакого отношения к вызову и возвращению значений. Конструктор не является функцией.
Так что объявления функций-членов класса ComplexType
void ComplexType(); ComplexType ComplexType();