|
Программирование >> Структурное программирование
В разделах Размышления об объектах в конце глав с 1 по 5 мы познакомились с основными принципами (т.е. с объектным мышлением ) и с терминологией (т.е. с объектным языком ) объектно-ориентированного программирования на С++. В этих специальных разделах мы также обсудили технику объектно-ориентированного проектирования: мы проанализировали типичную постановку задачи, которая требовала построения системы (например, модели лифта), определили, какие объекты необходимы для реализации системы, определили, какие атрибуты должны иметь объекты, определили, какими вариантами поведения должны обладать эти объекты, и указали, как объекты должны взаимодействовать друг с другом для достижения глобальной цели системы. Давайте проведем краткий обзор некоторых ключевых принципов и терминологии объектной ориентации. ООП инкапсулирует данные (атрибуты) и функции (варианты поведения) в совокупности, называемые объектами; данные и функции объекта тесно связаны друг с другом. Объекты обладают свойством скрытия информации. Это значит, что хотя объекты могут знать, как связываться друг с другом посредством хорошо определенного интерфейса, им обычно не позволено знать, как реализуются другие объекты - детали реализации спрятаны внутри самих объектов. Несомненно, можно ездить на автомобиле, не зная технических деталей его внутреннего функционирования - трансмиссии, выхлопной трубы и др. Мы увидим, почему скрытие информации так важно для разработки хорошего программного обеспечения. В С и других процедурно-ориентированных языках программирование стремится быть ориентированным на действия, тогда как в идеале программирование на С++ объектно-ориентированное. В С единицей программирования является функция. В С++ единицей программирования является класс, на основе которого в конечном счете создаются объекты. Программисты на С основное внимание уделяют написанию функций. Группы действий, выполняющие некоторую задачу, объединяются в функции, а функции группируются, чтобы образовать программу. Данные несомненно важны в С, но современная точка зрения состоит в том, что данные существуют в первзто очередь для поддержки действий, выполняемых функциями. Глаголы в описании проектируемой системы помогают программисту на С определить множество функций, которые будут совместно работать для реализации системы. Программисты на С++ основное внимание уделяют созданию своих собственных определяемых пользователем типов, называемых классами. Классы - это типы, определяемые программистом. Каждый класс содержит данные и набор функций, манипулирующих с этими данными. Компоненты-данные класса называются данными-элементами. Компоненты-функции класса называются функциями-элементами. Подобно тому как сущность встроенного типа, такого, как int, называется переменной, сущность определяемого пользователем типа (т.е. класса) называется объектом. Центром внимания в С++ являются не функции, а объекты. Имена существительные в описании проектируемой системы помогают программисту на С++ определить множество классов. Эти классы используются для создания объектов, которые будут совместно работать для реализации системы. Классы в С++ являются естественным продолжением структуры struct в С. Прежде чем рассматривать специфику разработки классов на С++, мы обсудим структуры и построим определенный пользователем тип, основанный на структуре. Слабости, которые мы выявим в этом подходе, помогут объяснить запись класса. 6.2. Определения структур Структуры - это составные типы данных, построенные с использованием других типов. Рассмотрим следующее определение структуры: struct Time { int hour; 0-23 int minute; 0-59 int second; 0-59 Ключевое слово struct начинает определение структуры. Идентификатор Time - тег (обозначение, имя-этикетка) структуры. Тэг структуры используется при объявлении переменных структур данного типа. В этом примере имя нового типа - Time. Имена, объявленные в фигурных скобках описания структуры - это элементы структуры. Элементы одной и той же структуры должны иметь уникальные имена, но две разные структуры могут содержать не конфликтующие элементы с одинаковыми именами. Каждое определение структуры должно заканчиваться точкой с запятой. Приведенное объяснение, как мы вскоре увидим, верно и для классов. Определение Time содержит три элемента типа int - hour, minute и second (часы, минуты и секунды). Элементы структуры могут быть любого типа и одна структура может содержать элементы многих разных типов. Структура не может, однако, содержать экземпляры самой себя. Например, элемент типа Time не может быть объявлен в определении структуры Time. Однако, может быть включен указатель на другую структуру Time. Структура, содержащая элемент, который является указателем на такой же структурный тип, называется структурой с самоадресацией. Структуры с самоадресацией полезны для формирования связных структур данных (см. главу 15). Предыдущее определение структуры данных не резервирует никакого пространства в памяти; определение только создает новый тип данных, который используется для объявления переменных. Переменные структуры объявляются так же, как переменные других типов. Объявление Time timeObject, timeArray[10], *timePtr; объявляет timeObject переменной типа Time, timeArray - массивом с 10 элементами типа Time, а timePtr - указателем на объект типа Time. 6.3. Доступ к элементам структуры Для доступа к элементам структуры (или класса) используются операции доступа к элементам - операция точка (.) и операция стрелка (->). Операция точка обращается к элементу структуры (или класса) по имени переменной объекта или по ссылке на объект. Например, чтобы напечатать элемент hour структуры timeObject используется оператор cout << timeObject.hour; Операция стрелка, состоящая из знака минус (-) и знака больше (>), записанных без пробела, обеспечивает доступ к элементу структуры (или класса) через указатель на объект. Допустим, что указатель timePtr был уже объявлен как указывающий на объект типа Time и что адрес структуры timeObject был уже присвоен timePtr. Тогда, чтобы напечатать элемент hour структуры timeObject с указателем timePtr, можно использовать оператор cout << timePtr->hour; Выражение timePtr->hour; эквивалентно (*timePtr).hour, которое разыменовывает указатель и делает доступным элемент hour через операцию точка. Скобки нужны здесь потому, что операция точка имеет более высокий приоритет, чем операция разыменования указателя (*). Операции стрелка и точка наряду с круглыми и квадратными скобками имеют второй наивысший приоритет (после операции разрешения области действия, введенной в главе 3) и ассоциативность слева направо. 6.4. Использование определенного пользователем типа Time с помощью Struct Программа на рис. 6.1 создает определенный пользователем тип структуры Time с тремя целыми элементами: hour, minute и second. Программа определяет единственную структуру типа Time, названную dinnerTime, и использует операцию точка для присвоения элементам структуры начальных значений 18 для hour, 30 для minute и О для second. Затем программа печатает время в военном (24-часовом) и стандартном (12-часовом) форматах. Заметим, что функции печати принимают ссылки на постоянные структуры типа Time. Это является причиной того, что структуры Time передаются печатающим функциям по ссылке - этим исключаются накладные расходы на копирование, связанные с передачей структур функциям по значению, а использование const предотвращает изменение структуры типа Time функциями печати. В главе 7 мы обсудим объекты const и функции-элементы const. Совет по повышению эффективности 6.1 Обычно структуры передаются вызовом по значению. Чтобы избежать накладных расходов на копирование структуры, передавайте аруктуры вызовом по ссылке. Совет по повышению эффективности 6.2 Чтобы избежать накладных расходов вызова по значению и вдобавок получить выгоды защиты исходных данных от изменения, передавайте аргументы большого размера как ссылки const. Существуют препятствия созданию новых типов данных указанным способом с помощью структур. Поскольку инициализация структур специально не требуется, можно иметь данные без начальных значений и вытекающие отсюда проблемы. Даже если данные получили начальные значения, возможно, это было сделано неверно. Неправильные значения могут быть присвоены элементам структуры (как мы сделали на рис. 6.1), потому что программа имеет прямой доступ к данным. Программа присвоила плохие значения всем трем элементам объекта dinnerTime типа Time. Если реализация struct изменится (например, время теперь будет представляется как
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |