И.А. Волкова, А.В. Иванов, Л.Е. Карпов - Основы объектно-ориентированного программирования. Язык программирования С++ (ЧБ) (1114895), страница 4
Текст из файла (страница 4)
. .}void ns2::print_ns(){cout << ”namespace ns2” << endl;}}При обращении к объекту, находящемуся во вложенном пространстве имен,например, из глобального пространства имен используются несколько квалификаторов:ns1::ns2::print_ns();Для сокращения записи имен используется объявление имени из пространства имен (using-объявление), например:using namespace ns1;В этом случае идентификаторы из указанной области можно использоватьбез квалификаторов вплоть до нового объявления пространства имен (using).Подробно об использовании using-объявления см. в [12, стр. 211-216, 924-926].Введение понятия пространства имен является одним из видов статическогополиморфизма: одинаковым идентификаторам придается разный смысл.Имена стандартной библиотеки С++ находятся в пространстве имен std.Поскольку функции, типы и константы стандартной библиотеки используютсяпрактически в каждой программе, рекомендуется для удобства использованияимен стандартной библиотеки в начало программы вставлять using-объявление:using namespace std;153.Классы и объекты С++Центральным понятием ООП является класс.
Класс используется для описания типа, на основе которого создаются объекты (переменные типа класс).Класс, как и любой тип данных, характеризуется множеством значений,которые могут принимать объекты класса, и множеством функций, задающихоперации над объектами.Пример: Имеется множество пар чисел (a, b) .Если для данного множества определить арифметические операции следующим образом:(a, b) + (c, d ) = (ad + bc, bd )(a, b) − (c, d ) = (ad − bc, bd )(a, b) *(c, d ) = (ac, bd )(a, b) / (c, d ) = (ad , bc),то это множество можно рассматривать как множество рациональных дробей:a( a , b) →bЕсли же арифметические операции определить по-другому:(a , b ) + (c, d ) = ( a + c, b + d )( a , b ) − (c, d ) = ( a − c, b − d )(a, b)*(c, d ) = (ac − bd , ad + bc)⎛ ac + bd bc − ad ⎞( a , b ) / ( c, d ) = ⎜ 2, 2⎟2c + d2 ⎠⎝ c +dэто же множество пар чисел можно рассматривать как множество комплексныхчисел: (a, b) → a + bi .Класс полноценно определяет тип данных как совокупность множествазначений и набора операций над этими значениями.3.1.Синтаксис описания классаclass Имя_класса { определение_членов_класса };Члены класса можно разделить на информационные члены и функции-члены(методы) класса.
Информационные члены описывают внутреннюю структуруинформации, хранящейся в объекте, который создается на основе класса. Методыкласса описывают алгоритмы обработки этой информации.Данные, хранящиеся в информационных членах, описывают состояниеобъекта, созданного на основе класса. Состояние объекта изменяется на основеизменения хранящихся данных с помощью методов класса. Алгоритмы, заложенные в реализации методов класса, определяют поведение объекта, то естьреагирование объекта на поступающие внешние воздействия в виде входныхданных.163.2.Управление доступом к членам классаПринцип инкапсуляции обеспечивается вводом в класс областей доступа:− private(закрытый, доступный только собственным методам)− public(открытый, доступный любым функциям)− protected (защищенный, доступный только собственным методам иметодам производных классов)Члены класса, находящиеся в закрытой области (private), недоступны дляиспользования со стороны внешнего кода.
Напротив, члены класса, находящиесяв открытой секции (public), доступны для использования со стороны внешнегокода. При описании класса каждый член класса помещается в одну из перечисленных выше областей доступа следующим образом:class Имя_класса {private:определение_закрытых_членов_классаpublic:определение_открытых_членов_классаprotected:определение_защищенных_членов_класса…};Порядок следования областей доступа и их количество в классе – произвольны.Служебное слово, определяющее первую область доступа, может отсутствовать. По умолчанию эта область считается private.В закрытую (private) область обычно помещаются информационные члены, ав открытую (public) область – методы класса, реализующие интерфейс объектовкласса с внешней средой.
Если какой-либо метод имеет вспомогательное значение для других методов класса, являясь подпрограммой для них, то его такжеследует поместить в закрытую область. Это обеспечивает логическую целостность информации.После описания класса его имя можно использовать для описания объектовэтого типа.Доступ к информационным членам и методам объекта , описанным в открытой секции, осуществляется через объект или ссылку на объект с помощьюоперации выбора члена класса ‘.’.Если работа с объектом выполняется с помощью указателя на объект, тодоступ к соответствующим членам класса осуществляется на основе указателяна член класса‘->’:class Х {public:char c;int f(){…}};17int main () {Х x1;Х & x2 = x1;Х * p = & x1;int i, j, k;x1.c = ‘*’;i = x1.f();х1.с = '+';j = x2.f();x1.c = ‘#’;k = p -> f();…}Объекты класса можно определять совместно с описанием класса:class Y {…} y1, y2;3.3.Классы и структуры С++Синтаксис класса в С++ совпадает с синтаксисом структуры С++:struct Имя_структуры { определение_членов_структуры };Класс С++ отличается от структуры С++ только определением по умолчанию первой области доступа в их описании (а также определением по умолчаниюспособа наследования, см.
раздел 10.3):− для структур умолчанием является открытый доступ (public)− для классов умолчанием является закрытый доступ (private).Различия в умолчаниях связаны с различиями целей создания таких конструкций. Структуры создавались для объединения и совместного использованияразнородных типов данных, например записей файлов. Класс предназначен дляопределения полноценного типа данных.В C++ объекты можно создавать также на основе структур и объединений(union).Структуру можно рассматривать как прообраз понятия класс.
Изначальноконцепция структуры (например, в Си) служила исключительно объединениюразнородных данных в единой конструкции для совместной обработки, то есть впонятии структуры присутствовала исключительно информационная составляющая. В С++ время в структуре могут быть и функции-члены, в том числе испециальные члены – конструкторы и деструкторы, о которых будет рассказанов следующих разделах.
Структуры наравне с классами можно использовать дляполноценного описания типов данных, включающего описания операций, применяемых к описываемому типу данных. Однако наличие информационныхчленов в открытой секции нарушает один из основных принципов ООП – принцип инкапсуляции.183.4.Манипуляции с состоянием объектаДля доступа к внутренним информационным членам объекта, созданного наоснове класса (чтение/запись), необходимо использовать специальные методыкласса, называемые модификаторами (setters) и селекторами (getters).
Они осуществляют подконтрольное считывание и изменение внутренних информационных членов. Так, если изменяется внутреннее информационное поле sizeобъекта класса stack, описывающее максимальный размер стека, то необходимоосуществить ряд действий по согласованному изменению других информационных членов (выделение дополнительной памяти и т.
д.):class stack {int* c1;int top, size;public:. . .int putnewsize(int ns){if (top > ns) return 1;int* nc1 = new int[ns];if (top > 0)for (int i = 0; i < top; i++)nc1[i] = c1[i];delete c1;c1 = nc1;size = ns;return 0;}};Таким образом, изменение информационных полей объекта должно осуществляться специальными методами, производящими изменение требуемого информационного поля согласованно с одновременным изменением других информационных полей.
Такие методы обеспечивают согласованность внутреннихданных объекта.3.5.Класс как область видимостиКласс является областью видимости описанных в нем членов класса. Идентификатор члена класса локален по отношению к данному классу. Классы могутбыть вложенными. Одноименные идентификаторы членов класса закрываютвидимость соответствующих внешних идентификаторов.Операция '::' позволяет получить доступ к одноименным объектам,внешним по отношению к текущей области видимости, в частности, к глобальнымфункциям и переменным, следующим образом:имя_класса :: имя_члена_класса:: имяили- для имен глобальных функций и переменных.19Пример:int ia1;void f1(int b1) {ia1 = ia1 + b1;}class x {int ia1;public:x(){ia1 = 0;}void f1(int b1){::f1(b1); // вызов глобальной функции}};int main(){x a2;a2.f1(2);return 0;}3.6.Объявление и определение методов класса.
Спецификатор inlineКаждый метод класса, должен быть определен в программе. Определитьметод класса можно либо непосредственно в классе (если тело метода не слишкомсложно и громоздко), либо вынести определение вне класса, а в классе толькообъявить соответствующий метод, указав его прототип.При определении метода класса вне класса для указания области видимостисоответствующего имени метода используется операции ‘::’:Пример:class x {int ia1;public:x(){ia1 = 0;}int func1();};int x::func1(){ … return ia1; }Это позволяет повысить наглядность текста, особенно, в случае значительного объема кода в методах.