На этом шаге мы продолжим разговор о конструкторах и рассмотрим реализацию доступности
компонентов класса.
Второй недостаток классов complex1 и goods, введенных с помощью служебного слова struct, - это общедоступность компонент. В любом месте программы, где "видно" определение класса, можно с помощью уточненных имен (например, имя_объекта.real или имя_объекта.imag) или с помощью указателя на объект и операции косвенного выбора "->" получить доступ к компонентным данным этого объекта. Тем самым не выполняется основной принцип абстракции данных - инкапсуляция (сокрытие) данных внутри объектов.
В соответствии с правилами языка C++ все компоненты класса, введенного с помощью ключа класса struct, являются общедоступными. Для изменения видимости компонент в определении класса можно использовать спецификаторы доступа. Спецификатор доступа - это одно из трех служебных слов
Появление любого из спецификаторов доступа в тексте определения класса означает, что до конца определения либо до другого спецификатора доступа все компоненты класса имеют указанный статус.
Защищенные (protected) компоненты классов нужны только в случае построения иерархии классов. При использовании классов без порождения на основе одних классов других (производных), применение спецификатора protected эквивалентно использованию спецификатора private.
Применение в качестве ключа класса служебного слова union приводит к созданию классов с несколько необычными свойствами, которые нужны для весьма специфических приложений. Пример такого приложения - экономия памяти за счет многократного использования одних и тех же участков памяти для разных целей. В каждый момент времени исполнения программы объект-объединение содержит только один компонент класса, определенного с помощью union. Все компоненты этого класса являются общедоступными, но доступ может быть изменен с помощью спецификаторов доступа protected (защищенный), private (coбcтвенный), public (общедоступный).
Изменить статус доступа к компонентам класса можно и с помощью использования в определении класса ключевого слова class. Все компоненты класса, определение которого начинается со служебного слова class, являются собственными (private), т.е. недоступными для внешних обращений. Так как класс, все компоненты которого недоступны вне его определения, редко может оказаться полезным, то изменить статус доступа к компонентам позволяют спецификаторы доступа protected (защищенный), private (coбcтвенный), public (общедоступный).
Итак, для сокрытия данных внутри объектов класса, определенного с применением ключа struct, достаточно перед их появлением в определении типа (в определении класса) поместить спецификатор private. При этом необходимо, чтобы некоторые или все принадлежащие классу функции остались доступными извне, что позволило бы манипулировать с данными объектов класса. Этим требованиям будет удовлетворять следующее определение класса "комплексное число":
//COMPLEX.СРР - определение класса "комплексное число". #include <iostream.h> // Класс с конструктором и инкапсуляцией данных: struct complex {// Методы класса (все общедоступные - public): // Конструктор объектов класса: complex (double re = 1.0, double im = 0.0) { real = re; imag = im; ) // Вывести на дисплей значение комплексного числа: void display(void) { cout << "real = " << real; cout << ", imag = " << imag; } // Получить доступ к вещественной части числа: double &re(void) { return real; ) // Получить доступ к мнимой части числа: double &im(void) { return imag; ) // Данные класса (скрыты от прямых внешних обращений): private: // Изменить статус доступа на "собственный". double real; // Вещественная часть. double imag; // Мнимая часть. };
По сравнению с классом complex1 в новый класс complex, кроме конструктора, дополнительно введены компонентные функции &re() и &im(), с помощью которых можно получать доступ к данным объектов. Они возвращают ссылки соответственно на вещественную и мнимую части того объекта, для которого они будут вызваны.
Напомним, что для конструктора не задается тип возвращаемого значения. Существуют особенности и в вызове конструктора. Без явного указания программиста конструктор всегда автоматически вызывается при определении (создании) объекта класса. При этом используются умалчиваемые значения параметров конструктора. Например, определив объект ее с неявным вызовом конструктора
complex CC;
получим при вызове CC.re() значение 1.0. Функция CC.im() вернет ссылку на CC.imag, и этот элемент объекта CC будет иметь значение 0.0, заданное как умалчиваемое значение параметра конструктора.
На следующем шаге мы завершим разговор о конструкторах и рассмотрим другую компонентную функцию, называемую деструктором.