Страница 11 из 48 Инициализация объекта: параметры и инициализаторы Совместно используемые функции различаются списками параметров. В этом смысле конструкторы подобны функциям. Рассмотрим определение конструктора с параметрами. Мы расположим его за пределами класса. При этом в классе располагается прототип конструктора, а его имя при определении заменяется квалифицированным именем: class ComplexType { ::::: public: ComplexType(double keyReal, double keyImag, char keyCTcharVal, int keyX); ::::: }; ::::: ComplexType::ComplexType(double keyReal, double keyImag, char keyCTcharVal, int keyX) { cout << "This is ComplexType(" << keyReal << "," << keyImag << "," << (int)keyCTcharVal << "," << keyX << ")" << endl; real = keyReal; imag = keyImag; CTcharVal = keyCTcharVal; x = keyX; };
А вот и подходящее определение. Мы расположим его в функции main: ComplexType CDw2(100,100,0,0); /* Создаётся объект типа ComplexType под именем CDw2 с определёнными значениями. */ int iVal(10); /* Аналогичным образом может быть определён и проинициализирован объект основного типа */
Заметим, что к такому же результату (но только окольными путями) приводит и такая форма оператора определения: ComplexType CDw2 = ComplexType(100,100,0,0); И снова мы встречаем случай определения объекта посредством постфиксного выражения. Здесь опять можно говорить о явном обращении к конструктору с передачей ему параметров. Выражения явного приведения типа здесь построить невозможно, поскольку за заключённым в скобочки именем типа должно стоять унарное выражение. Заметим, что не может быть операторов определения переменных с пустым списком инициализаторов: ComplexType CDw1(); // Это ошибка! int xVal(); // Это тоже не определение.
Независимо от типа определяемой переменной, подобные операторы воспринимаются транслятором как прототипы функций с пустым списком параметров, возвращающие значения соответствующего типа. При объявлении и определении функций C++ позволяет производить инициализацию параметров. Аналогичным образом может быть модифицирован прототип конструктора с параметрами: ComplexType(double keyReal = 0, double keyImag = 0, char keyCTcharVal = 0, int keyX = 0);
Но при этом программист должен быть готовым к самым неожиданным ситуациям. Последняя модификация прототипа вызывает протест со стороны транслятора. Он не может теперь однозначно соотнести оператор определения объекта с одним из вариантов конструктора. Перед нами тривиальный случай проявления проблемы сопоставления. Мы закомментируем определение самого первого конструктора (конструктора без параметров) и опять всё будет хорошо. Теперь вся работа по определению и инициализации объектов обеспечивается единственным конструктором с проинициализированными параметрами. Конструктор, управление которому передаётся в результате выполнения оператора определения без параметров, называется конструктором умолчания. К конструкторам умолчания относятся следующие конструкторы: - конструктор, автоматически создаваемый транслятором,
- определяемый программистом конструктор с пустым списком параметров,
- конструктор с проинициализированными по умолчанию параметрами.
Внесём ещё одно изменение в текст нашей программы. На этот раз мы добавим спецификатор const в объявление данного-члена класса x: class ComplexType { ::::: const int x; ::::: }
И опять возникают новые проблемы. На этот раз они связаны с попыткой присвоения значения константе. |