Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Основные понятия объектно-ориентированного программирования)

Содержание:

ВВЕДЕНИЕ

С развитием компьютерной техники появился машинный язык,
с помощью которого программист мог задавать команды, оперируя
с ячейками памяти, полностью используя возможности машины.

Однако использование большинства компьютеров на уровне машинного языка затруднительно, особенно это касается ввода-вывода. Поэтому от его использования пришлось отказаться.

На современном этапе появилось множество языков, которые позволяют выполнять самые различные по свой структуре и возможностям функции.

В дальнейшем, с развитием языков программирования, появилась возможность адаптировать обработку данных с помощью созданных программных продуктов, что являлось очень удобным, поскольку программисты могут написать программу для конкретной предметной области.

Вместе с этим начали создаваться программы с объектно-ориентированным подходом. Эффективность и необходимость создания таких программ является актуальными в наше время, поскольку основой для удобного пользования программой является, например, дружественный графический интерфейс пользователя, который без знания указанной парадигмы программирования - невозможен.

Целью работы является рассмотрения принципов объектно-ориентированного программирования на языке С++.

Исходя из поставленной цели в работе необходимо решить следующие основные задачи:

– рассмотреть основные определения и классификацию языков программирования;

– охарактеризовать объектно-ориентированный язык программирования С++;

  • рассмотреть принципы объектно-ориентированного программирования;
  • рассмотреть применение шаблонных классов в С++;
  • создать программный продукт, который демонстрирует использование принципов ООП.

Объект исследования – инструментальное программное обеспечение.

Предмет исследования – объектно-ориентированные языки программирования.

По мере развития вычислительной техники возникали разные методики программирования. На каждом этапе создавался новый подход, который помогал программистам с растущим усложнением программ.

1.ОСНОВНЫЕ ПОНЯТИЯ О ЯЗЫКАХ ПРОГРАММИРОВАНИЯ

Основы теории языков программирования

Рассмотрим понятия языка программирования.

Языком программирования называется система обозначений, которая служит для точного описания алгоритмов или инструкций программ для ЭВМ. Стоит отметить, что языки программирования – это искусственные языки. Они отличаются от естественных языков ограниченным числом служебных слов и строгими правилами записи операторов (команд). При их применении по назначению
не допускается свободное толкование выражений (что характерно для естественных языков).[10]

Можно сформулировать перечень требований, которые выставляются
к языкам программирования.

Основные требования, которые предъявляются к языкам программирования, следующие:

– единство - использование одинаковых символов для обозначения родственных или одинаковых понятий в различных частях алгоритма. Количество данных символов должно быть минимальным;

– наглядность – это использование в языке программирования уже существующих символов, которые хорошо известны и понятны как пользователям ЭВМ, так и программистам;[2]

– модульность - описания сложных алгоритмов с помощью совокупности простых модулей, что могут быть составлены в разных частях программы
и использованы в более сложных алгоритмах;

– гибкость - возможность удобного и несложного описания распространенных методов математических вычислений с помощью набора изобразительных средств конкретного языка программирования;[1]

– однозначность - запись любого алгоритма должна быть однозначной и не допускать двойственных трактовок. Отсутствие указанного требования может привести к неправильным результатам функционирования программы.

Язык программирования определяет совокупность лексических, семантических и синтаксических правил, которые используются для составления компьютерной программы. Он дает возможность программисту точно определять, на какие именно события будут реагировать персональные компьютеры при выполнении программы, как будут организованы хранение и передача данных,
а также какие действия нужно выполнять над данными при разных условиях. [6]

Со времени создания первых ЭВМ человечество придумало более 2,5 тысяч языков программирования. Их число пополняется каждый год новыми, зачастую специализированными, языками. Некоторыми из них умеет пользоваться лишь небольшое число разработчиков, другие – известны миллионам людей. Профессиональные разработчики иногда применяют более десятка различных языков программирования в своей работе.[7]

Машинный вид команды программы, состоящий из символов «0»
и «1», указывает, какое действие должен выполнять центральный процессор. Значит для того, чтобы задать ЭВМ последовательность инструкций, которые ему надо выполнить, нужно описать последовательность двоичных кодов для соответствующих команд.

Программы, отображенные в машинном коде, состоят из тысяч команд,
а их создание является занятием сложным и утомительным. Программисту необходимо помнить комбинацию единиц и нулей двоичного кода
для каждой программы, а также бинарные коды адресов данных, которые используются при её выполнении. [1]

Намного проще писать программу на языке программирования, который более близок к естественному языку, а работу по «переводу» данной программы
в машинный код поручить компьютеру.

Рассмотрим краткую поэтапную историю языков программирования.

  1. Машинный язык (начало 50-х годов XX ст.). Программы
    на машинном языке являлись очень длинными последовательностями двоечных цифр и машинно-зависимыми (для каждой ЭВМ нужно было составлять свою программу, которая подходила бы под ее архитектуру).[6]
  2. Ассемблер (середина 50-ых годов XX ст.). Вместо написание программ на бинарном коде программисты могли пользоваться операторами языка Ассемблер (ADD, MOV, SUB и прочими), которые похожи на аббревиатуры английских слов. Программы на этом языке также являются машинно-зависимыми. В тот период для преобразования написанного кода в машинный использовался компилятор – специальная программа для перевода инструкций Ассемблера в машинный код.
  3. Языки типа Fortran.[4]

С конца 50-ых гг. XX ст. начали создаваться первые машинно-независимые языки программирования, но для каждого из них были разработаны компиляторы.

Примерами таких языков являются:

– FORTRAN – для технических и научных расчетов;

– COBOL – для коммерческих приложений;

– BASIC – универсальный язык для начинающих.

  1. Алгоритмические языки программирования. [10]

С конца 70-ых г. XX ст. начали создаваться такие языки программирования, что позволяли перейти программисту к структурному программированию (применение операторов выбора, ветвления, цикла и отказ от использования операторов перехода (например, goto). К таким языкам относятся:

– Pascal;

–Си.

  1. Языки объектно-ориентированного направления.

В основу таких языков положены программные структуры, которые объединяют методы и данные их обработки. В объектно-ориентированных языках сохранялись алгоритмические методы программирования. Для них разработаны IDE - интегрированные среды программирования, которые позволяли визуально проектировать графический интерфейс приложений. К языкам рассматриваемого этапа относяться: [2]

– С++ – усовершенствование алгоритмического языка Си;

– Object Pascal – создан на основе Pascal.

– Visual Basic – для создания приложений с оконным интерфейсом для ОС Windows.

  1. Языки программирования, использующиеся в компьютерных сетях.

В начале 90-х годов XX ст. в связи с быстрым развитием Интернета созданы языки программирования, обеспечивающие кроссплатформенную совместимость. На подключенных компьютерах к Интернету с различными ОС могли запускаться одни и те же программные продукты. Исходная программа компилировалась
в промежуточный код, который обрабатывался на компьютере встроенной виртуальной машиной. К таким языкам относяться:[4]

– Java - объектно-ориентированный язык, разработан для создания сетевого ПО;

– JavaScript – язык сценариев для Web-страниц.

  1. Языки программирования платформы .NET.

IDE Visual Studio .Net разработана корпорацией Microsoft и позволяет создавать графические приложения на разных объектно-ориентированных языках программирования:[5]

– Visual Basic .Net;

– C# и J;

– Visual J#.

1.2. Классификации языков программирования

Все языки программирования классифицируются по четырём основным признакам: процедурные, объектно-ориентированные, логические
и функциональные. [2]

Процедурным программированием называется такой вид программирования, при котором программа состоит из последовательности инструкций и отделена
от данных

Декларативные языки программирования – языки построения и объявлений структур. К ним относят логические и функциональные языки программирования.
В данных языках явно не производятся алгоритмические действия, алгоритм не задается программистом, а проектируется самой программой.

В декларативных языках программирования производится построение какой-либо системы или структуры, то есть объявляются (декларируются) некоторые свойства создаваемого объекта. Такие языки получили широкое использование
в системах автоматизированного проектирования, в моделировании, в CAD-пакетах, системах искусственного интеллекта.[1]

К объектно-ориентированным языкам программирования относятся

языки, в которых функции и переменные группируются в специальные конструкции – классы. Благодаря этому программисты достигают более высокого уровня структуризации программ. Экземпляры, порождённые от созданных классов, вызывают методы (процедуры или функции), которые меняют некоторые свойства (переменные) объектов. С формальной стороны объектно-ориентированный метод написания программ основан на процедурной модели. [7]

Сетевые языки – это языки, которые предназначены для организации взаимодействия компьютеров, которые подключены в локально-вычислительную сеть. Они построены на так называемых принципах интерпретации – интерактивной, построчной обработки строк кода программы, описывающего сценарий сетевого взаимодействия компьютеров.

Машинно-ориентированные языки – языки, изобразительные средства
и наборы операторов которых существенно зависят от архитектуры ЭВМ (структуры памяти, внутреннего языка и т.д.). Такие языки программирования позволяют использовать все особенности и возможности машинно-зависимых языков: [8]

  • возможность использования определенных аппаратных ресурсов;
  • высокое качество программ (скорость выполнения и компактность);
  • предсказуемость заказов памяти и объектного кода;
  • трудоемкость составления программ;
  • для составления эффективно работающих программ необходимо знать перечень команд и особенности архитектуры данной ЭВМ; [9]
  • низкая скорость программирования;
  • невозможность использования программ на ЭВМ других типов.

Машинно-независимые языки – средство описания алгоритмов задач
и информации, которые подлежат обработке. Их удобно использовать для широкого круга программистов, они не требуют знания особенностей архитектуры ЭВМ
и ВС.[7]

Такие языки называют высокоуровневыми языками программирования. Также командные последовательности (подпрограммы, процедуры), которые часто используются в машинных программах, представляются отдельными операторами
в высокоуровневых языках. Программист получил возможность сосредоточиться
на особенностях алгоритма, а не расписывать на уровне машинных команд вычислительный процесс.

С расширением области применения вычислительной техники возникает необходимость формализовать постановку и решение различных классов задач. Необходимо создавать такие языки программирования, которые позволили
бы описать требуемые алгоритмы, ориентированные на решение конкретных проблем.[4]

Например, к проблемным языкам относятся следующие:

– Алгол, Фортран – языки для решения математических задач;

– Слэнг, Simula – для моделирования процессов;

– Снобол, Лисп – для работы с использованием списочных структур.

Универсальные языки создаются для широкого круга заданий: научных, коммерческих, моделирования и т.д. Самый первый универсальный язык разработан фирмой IBM – Алгол-68. Он позволяет выполнять работу с разрядами, символами, числами с плавающей и фиксированной запятой, имеет систему операторов управления форматам. Язык учитывает возможности прерывания, имеет соответствующие для этого операторы. Так же предусмотрена возможность параллельного программирования. [7]

Появление новых возможностей аппаратного обеспечения поставило задачу перед программистами – создать программные средства, которые обеспечивают оперативное взаимодействие пользователя с ЭВМ. Их назвали диалоговыми языками.

Работы по созданию велись в двух основных направлениях:

– создавались управляющие языки для оперативного воздействия
на выполнение задач;

– разрабатывались языки, которые обеспечивали описание алгоритмов решения. [2]

Язык Бэйсик является одним из примеров диалоговых языков.

Бэйсик использует обозначения, которые похожи на обычные математические выражения. Некоторые операторы представлены упрощенными вариантами функций и операторов языка программирования Фортран.

Непроцедурные языки составляют совокупность языков, которые описывают организацию данных, что обрабатывается по фиксированным алгоритмам.

Позволяя четко описать как задачу, так и действия, необходимые для
её решения, таблицы решений дают возможность определить, какие условия должны выполнятся прежде чем перейти к какому-либо действию. [7]

Одна таблица решений, которая характеризует некоторую ситуацию, содержит все блок-схемы реализаций алгоритмов.

Отметим, что табличные методы, легко осваиваемые специалистами разных профессий.

Программы, составленные на таких языках, удобно описывают сложные алгоритмы, возникающие в системном анализе.

2. ОСНОВЫ ОБЪЕКТНО_ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ В С++

2.1. Принципы объектно-ориентированного программирования

Объектно-ориентированный подход к программированию является приоритетным при создании подавляющего большинства программных проектов.
В окончательном виде каждая программа представляет собой набор инструкций для процессора. И чем выше является уровень языка, тем
в более простой форме записываются одни и те же действия.
С наращиванием объема программ становится нужным структурировать информацию, выделять в ней главное и отбрасывать несущественное.
Этот процесс называется повышением степени абстракции программы. [9]

Первым шагом к повышению абстракции является использование функций, которое позволяет после написания и отладки функции дистанцироваться от деталей реализации, поскольку для вызова функции надо знать только ее интерфейс. [6]

Следующий шаг – объявление собственных типов данных, которые позволяют структурировать и группировать информацию, подавая ее в более естественном виде. Поскольку для работы с собственными типами данных требуются специальные функции, поэтому считается естественное группировать их вместе
с объявлением этих типов в одном месте программы и определенным образом отделить от остальных ее частей. Объединения
в модуле объявлений типов данных и функций, предназначенных для работы
с этими типами, вместе со скрытием от пользователя модуля несущественных деталей, является дальнейшим развитием структуризации программы. [3]

Все три упомянутых выше методы увеличивания абстракции имеют целью упростить структуру программы, то есть представить ее в виде небольшого количества более мощных блоков. Это позволяет управлять большим объемом информации, а, следовательно, успешно налаживать большие программы.

Введение понятия класса является развитием идей модульности.
В классе сочетаются структуры данных и функции их обработки. Идея классов является основой объектно-ориентированного программирования. [1]

Программы на C++ широко используют классы. Класс является типом данных, который определяет пользователь. В классе задаются свойства
и характер определенного предмета или процесса в виде полей данных
и функций для работы с ними. Например, класс телефон может иметь поля данных: номер, тип телефона (кнопочный или дисковый) и функции работы
с телефоном: звонок, набор номера, соединения с абонентом и тому подобное. Группировка данных и кодирования их одной переменной упрощает процесс программирования и увеличивает возможность повторного использования кода. Существенным свойством класса является то, что детали его реализации скрыто от пользователей класса
по интерфейсу. Это защищает их от случайных изменений. Интерфейсом класса является заголовки его методов.[4]

Идея классов отражает строение объектов реального мира. Ведь каждый объект или процесс имеет набор определенных характеристик или различий, иначе говоря, определенные свойства и поведение. Так, характеристиками автомобиля является марка, цвет, максимальная скорость, мощность двигателя и тому подобное; характеристиками усилителя является частотный диапазон, мощность, коэффициент нелинейных искажений и т.д. Функциональные возможности объектов тоже отличаются: автомобиль может ездить, усилитель – повышать уровень сигналов.
А пользоваться объектами можно, не зная их внутреннего строения. [8]

Например, управлять автомобилем можно, не имея никакого представления
о строении его двигателя или любых других его частей. Каждый класс занимает определенное место в иерархии классов, например, все автомобили относятся
к классу наземный транспорт (более высокого в иерархии), а класс автомобиля содержит много разновидностей автомобилей: грузовые, легковые, внедорожники
и др. [9]

Любой класс определяет категорию объектов, а каждый объект является экземпляром некоторого класса. ООП – это методика, которая концентрирует основное внимание программиста на связи между объектами, а не на деталях
их реализации.

Основными принципами на которых базируется ООП, являются: [5]

– инкапсуляция;

– наследование;

– полиморфизм.

Инкапсуляцией называется сочетание данных с функциями
их обработки вместе со скрытием лишней для пользования этими данными информации. Инкапсуляция повышает уровень абстракции программы, позволяет изменять реализацию класса без модификации основной части программы
и использовать класс в другом окружении.

Наследование – это возможность создания иерархии классов, когда классы-потомки наследуют свойства своих базовых классов (предков), могут изменять
эти свойства и приобретать новые. Свойства базовых классов (предков)
при наследовании не описываются, что сокращает объем программы.

Полиморфизм – это возможность использовать в разных классах иерархии одно имя для обозначения близких по смыслу действий и гибко выбирать соответствующие действия в ходе выполнение программы. [3]

Объектно-ориентированное программирование в никоем образе не связано
с процессом выполнение программы, а является только новым способом
ее организации, то есть новой парадигмой программирования (парадигма - набор теорий и методов, которые определяют способ организации знаний).

Существует три группы языков программирования, которые связаны
с понятием класс: объектно-ориентированные, объектные, объектно-основанные. [4]

Объектно-ориентированные языки в полном объеме поддерживают парадигму ООП: инкапсуляции, наследования и полиморфизма. Типичными представителями таких языков является C++, Java, C#.

К объектным относятся языки программирования, которые поддерживают только инкапсуляцию и позволяют создавать объекты – это языки Visual Basic
(до шестой версии включительно) и Ada. [8]

К объектно-основанным языкам программирования относят языки, которые могут использовать существующие объекты, но не имеют механизма создания объектов пользователя. Язык JavaScript является объектно-основанным языком программирования.

К программированию основные понятия ООП перешли из других областей знаний, таких как философия, логика и математика, причем,
без особых изменений, по мере того, что касается сущности этих понятий.

Классом является абстрактный тип данных, определяемый пользователем,
и изображает модель реального мира в виде данных и функций их обработки.

Данные класса называют полями или данными-членами, а функции класса – методами или функциями-членами. Поля и методы называются элементами класса. [10]

В основном спецификация класса состоит из двух частей:

– объявления класса - в нем прописаны все поля и методы (элементы данных) класса на уровне интерфейса в терминах функций-элементов;

– определение методов класса, то есть реализации конкретных функций членов данного класса.

Объявление класса имеет следующий формат:

class <имя класса>

{

[private:] <объявления скрытых элементов класса>

protected: <объявления элементов, доступных только потомкам>

public <объявления общедоступных элементов>

}; // Объявление завершается точкой с запятой

Спецификаторы доступа private, protected и public управляют видимостью элементов класса. Элементы, определенные после ключевого слова private, доступны только в этом классе. Этот вид доступа принято
в классе по умолчанию. [4]

Спецификатор доступа protected содержит поля и методы, которые скрыты от всех, кроме потомков класса. [1]

Поля и методы, определенные ключевым словом public, доступны вне класса, то есть к ним можно обращаться непосредственно из программы, используя объекты класса. Содержание общедоступного раздела public составляет абстрактную часть конструкции, то есть общедоступный интерфейс, который содержит прототипы функций-элементов или полное определение (для небольших функций).[6]

Рассмотрим пример объявления класса:

class myclass

{

private: // скрытие элементов

int a;

public: // Общедоступные элементы

void set_a (int num)

{

a = num;

} // Метод, который изменяет значение поля

int get_a ()

{

return a;

} // Метод, который возвращает значение поля};

В этом примере класс myclass содержит только одно поле данных a, которое имеет тип int, причем это поле доступно только в классе, так оно объявлено
с ключевым словом private. Обращение к этому полю из программы невозможно
и повлечет ошибку. [4]

Однако доступ к данным можно организовать с помощью методов, которые еще называют методами доступа. Такими в классе myclass есть два метода: set_a(), который присваивает полю значение, и get_a(), который возвращает значение поля. Эти методы доступны за пределами класса, поскольку они объявлены ключевым словом public.

Тела обоих методов (код функций) содержатся непосредственно
в объявлении класса. Здесь реализация функций не означает, что код функции размещается в памяти. Это произойдет лишь при создании объекта класса. [6]

Методы класса, определенные подобным образом, по умолчанию являются встроенными функциями. При увеличении методов по количеству и объему, определение функций класса как встроенных может вызвать беспорядки
в объявлении класса. Чтобы избежать этого, функции внутри класса зачастую
не определяются, а только объявляются (т.е. размещаются их прототипы), а само определение функций происходит в другом месте.

2.2.Основная информация о С++

С момента своего создания язык программирования C++ потерпел три значительных совершенствования, то есть каждый раз он как дополнялся новыми средствами, так и в чем-то был изменен.[9]

Первой ревизии язык C++ была подвергнут в 1985 г., второй –в 1990 г. Третья ревизия состоялась в процессе его стандартизации, которая началась
в начале 1990-х годов. Для этого специально был сформирован ISO-комитет, который в январе 1994 года принял первый проект стандарта языка С++.

В данный проект были внесены средства, впервые определенные Бьярном Страуструпом.

После завершения работы над начальным стандартом языка программирования C++, произошло событие, что заставило расширить полученный стандарт. Речь идет о создании библиотеки STL – Стандартной Библиотеки Шаблонов – набора обобщенных функций, которые используются для обработки данных. [1]

На собрании ISO-комитета участники проголосовали за внесение STL
в спецификацию языка C++. Именно эта библиотеки расширила сферу применения средств C++ далеко за пределами первоначального
ее определения.

Отметим, что в стандартной библиотеке C++ содержится стандартная библиотека языка Си с небольшими изменениями, что делают ее более гибкой
и функциональной. Другая часть библиотеки C++ основана
на библиотеке STL. Она предоставляет такие инструменты, как контейнеры (векторы, списки) и итераторы (аналог указателей), которые предоставляют доступ
к контейнерам так, как и к массивам с помощью индексов. [5]

Так же библиотека STL позволяет работать и с другими контейнерами (ассоциативными списками, очередями, стеками). Используя шаблоны, есть возможность писать обобщенные алгоритмы, которые способны работать
с различными последовательностями или контейнерами, доступ к членам которых обеспечивается итераторами.[2]

Аналогично языку программирования С, для подключения библиотек используется директива #include. Всего в стандарте языка C++ определено больше 50 таких файлов.

Библиотека STL до внесения ее в стандарт языка программирования C++ была сторонней разработкой фирм HP и SGI. Принятый стандарт языка не называет
ее термином STL, поскольку она стала неотъемлемой частью С++, однако разные программисты используют это название до сих пор, чтобы отличать ее от остальных частей стандартной библиотеки.

Изучение любого иностранного языка начинается с алфавита. Именно
из элементов алфавита состоят слова, конструкции и выражения, которые
в итоге образуют осмысленный текст. Применим этот принцип и к языку С++.

Стандарт языка С++ разделяет алфавит на четыре части: основной набор текстовых символов, множество универсальных символов, основной набор управляющих символов и основной набор расширенных управляющих символов.[3]

В свою очередь, на их основе создается набор управляющих символов и набор расширенных управляющих символов. Рассмотрим каждый из них подробнее.

Основной набор текстовых символов состоит из 96 символов: пробел, четырех управляющих символов (горизонтальная табуляция (\t), вертикальная табуляция (\v), перевод страницы (\f), переход на новую строку (\n) и символов ASCII (American Standard Code for Information Interchange – американский стандартный код для информационного обмена) – 91 символ. [1]

Как правило, этих символов вполне достаточно для создания практически любой программы.

Универсальные символы кодируются последовательностями
из четырех или восьми шестнадцатеричных цифр, называемых универсальными именами (universal-name-symbol).

/ Uhhhhhhhhh

/ uhhhh

Здесь символ h обозначает шестнадцатеричную цифру.[7]

Кроме символов, используемых для кодирования элементов программ (идентификаторов, комментариев, литералов и т.п.), в языке С++ используются так называемые управляющие символы, с помощью которых можно выполнять небольшое количество операций, связанных, как правило, с вводом и выводом данных.

Если программисту не важно, как завершена программа,
и он не предусматривает определенной реакции операционной системы, перед именем main() следует поставить ключевое слово void. Для того чтобы вернуть управление операционной системе можно или выполнить оператор return, или дождаться, пока поток управления достигнет последней фигурной скобки.[9]

Тривиальная программа, рассматриваемая выше, конечно, является исключением. Каждая реальная программа выполняет, по крайней мере, операции ввода и вывода, а для этого ей нужны стандартные функции, входящие
в процедурную систему ввода-вывода языка С, или операторы, которые являются частью объектно-ориентированной системы ввода-вывода языка С++ . Чтобы использовать эти функции и операторы, необходимо включить в программу заголовочный файл <stdio.h> или заголовок <iostream>.

Для этого в директиве #include указывается имя соответствующего заголовочного файла, заключенное в угловые скобки.[6]

Препроцессор – это программа, которая обрабатывает текст программы
на первом этапе компиляции. Она выполняет макроподстановку, условную компиляцию и включение именуемых файлов. Каждая из этих операций кодируется в виде особого оператора (директивы), начинающийся символом #. Как правило, препроцессор используется для включения в программу файлов, в которых определены стандартные функции.

Препроцессор не выполняет синтаксический анализ текста. Он просто распознает макроподстановки и выполняет их.[2]

Каждая директива должна располагаться в отдельной строке программы. При этом необходимо внимательно следить за пробелами внутри директив. Некоторые из них не имеют значения, а другие приводят к ошибкам.

3. СОЗДАНИЕ ПРОГРАММНОГО ПРОДУКТА С ПОМОЩЬЮ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ЯЗЫКА ПРОГРАММИРОВАНИЯ С++

3.1.Практическое применение шаблонов классов в С++

Шаблон класса - это обобщенное определение класса, которое содержит типы данных в качестве параметров, с которого компилятор автоматически создает класс для заданных пользователем типов данных. Когда компилятор создает по шаблону класса конкретный класс для определенных пользователем типом данных, говорится, что он создал шаблонный класс. В связи с этим шаблон класса называют иногда родовым классом.[2] Синтаксис объявления шаблона класса имеет следующий вид:[5]

template <class T1 | T1 идент1>,

class T2 | T2 идент 2,

...

class Tn | Tn идент n>

class имя_класса

{

// Тело класса

}

По ключевому слову template идет один или несколько параметров
в угловых скобках и разделенных между собой запятыми. Каждый параметр является:[1]

– или ключевым словом class, за которым следует имя типа;

– или именем типа, за которым следует идентификатор.

После этого идет объявления класса. Объявления и инициализация класса используют список параметров шаблона. Для задания параметризованных типов данных вместо ключевого слова class в угловых скобках может также использоваться ключевое слово typename. Как и в случае шаблонных функций, ключевое слово class или typename показывает, что параметр задает или встроенный, или определенный пользователем тип данных.

Параметры шаблона, которые идут по ключевому слову class
или typename, называют параметризованным типами. Параметры шаблона, которые состоят из имени типа и следующего за ним идентификатора, информируют компилятор о том, что параметром шаблона является константа указанного типа.
В связи с этим параметры называются нетипичными. Имя формального параметра
в списке параметров шаблона класса должно быть уникальным. Функции-члены шаблона класса могут определяться в теле класса (то есть как встроенные) или вне тела класса. [10]

Таким образом, список параметризованных типов и нетипичных констант указывается дважды. Первый раз - после ключевого слова template, он указывается точно так же, как при объявлении шаблона. Второй раз - после имени класса - он указывается снова в угловых скобках, но на этот раз перечисляются только параметризованные типы и нетипичные константы.[2]

Во всем остальные определения функции-члену не отличаются
от обычного. Если необходимо объявить функцию-член статической
или встроенной, то модификатор указывается по списку параметризованных типов и нетипичных констант перед типом функции, который возвращается.

Стоит отметить, что невозможно определить внутренний шаблонный класс
в теле другого шаблонного класса, но ничто не мешает вам использовать ранее объявленный шаблонный класс при объявлении и определении другого. Рассмотрим в качестве примера определения класса для обобщенного связного списка, который предназначен для работы с определенным пользователем типом данных:

Процесс построения порожденного класса компилятором называют конкретизацией шаблонного класса. Шаблонный класс конкретизируется присоединением к его имени полного списка фактических параметров, которые вкладываются в угловые скобки. При этом компилятор создает порожденный класс, в котором:

• каждый параметр типа class T заменяется именем действительного типа;

• каждый параметр типа Type идент заменяется константным выражением.

Фактические аргументы для нетипичных параметров должны исчисляться
на стадии компиляции, поскольку именно на этой стадии проводится конкретизация шаблонных классов. [3]

В шаблонном классе можно объявлять статистические данные-члены. В этом случае для каждой конкретизации шаблонного класса будет построена своя совокупность статических данных-членов.

Для статических данных-членов обычного класса память выделяется сразу после определения класса. Для статических данных-членов шаблонного класса память выделяется при каждой конкретизации класса. Доступ
к статическому члену шаблонного класса осуществляется через конкретизацию этого класса.

Шаблоны предоставляют определенные преимущества
при программировании, связанные с широкой применимости кода и легким его сопровождением. В общем, этот механизм позволяет решать такие задачи, для которых используется полиморфизм. С другой стороны, в отличие от макросов, они позволяют обеспечить безопасное использование типов данных. Однако
с их использованием связаны и некоторые недостатки:

• программа содержит полный код для всех порожденных представителей шаблонного класса или функции;

• не для всех типов данных предусмотрена реализация класса или функции оптимальна.

Преодоление второго недостатка возможно с помощью специализации шаблона.

3.2. Реализация программного продукта «Матричная арифметика»
с помощью шаблонного класса

Напишем шаблонный класс на языке С++, реализующий матричную арифметику: сложение, вычитание, умножение, транспонирование матриц, умножение матрицы на число, умножение вектора на матрицу, вывод элементов матрицы на дисплей, проверка матриц на равенство, нахождение определителя матрицы, нахождение следа матрицы.

Разработаем и реализуем тестовое приложение с оконным интерфейсом, демонстрирующее работу с описанным классом.[8]

С помощью среды интегрированной разработки C++ Builder создадим оконный интерфейс для приложения (рисунок 1)

Рисунок 1 – Проектирование интерфейса для программы «Матричная арифметика»

Реализация программы состоит из файла Matrix.cpp, в котором находится описание шаблонного класса и все его функций и модуля с основной программой.

Рассмотрим кратко основные части кода реализации шаблонного класса.

//Объявление шаблонного класса

template<class T>

class Matrix {

//Описание открытых полей класса

public:

//конструктор

Matrix(int n, int m) {

rows = n;

cols = m;

mtx = new T*[rows];

for(int i=0; i<rows; i++) {

mtx[i] = new T[cols];

}

}

//реализация конструктора копирования

Matrix(const Matrix<T> &m) {

rows = m.rows;

cols = m.cols;

mtx = new T*[rows];

for(int i=0; i<rows; i++) {

mtx[i] = new T[cols];

for(int j=0; j<cols; j++) {

mtx[i][j] = m.get(i,j);

}

}

}

//деструктор класса

~Matrix() {

if(mtx == NULL)

return;

for(int i=0; i<rows; i++) {

delete [] mtx[i];

}

delete [] mtx;

}

//функция для сложения матриц

Matrix<T> add(const Matrix<T> &m) {

//новая матрица

Matrix<T> res(rows, cols);

for(int i=0; i<rows; i++) {

for(int j=0; j<cols; j++) {

res.mtx[i][j] = get(i,j)+m.get(i,j);

}

}

return res;

}

//функция для вычистания матриц

Matrix<T> substract(const Matrix<T> &m) {

//новая матрица

Matrix<T> res(rows, cols);

for(int i=0; i<rows; i++) {

for(int j=0; j<cols; j++) {

res.mtx[i][j] = get(i,j)-m.get(i,j);

}

}

return res;

}

//функция для транспонирования матрицы

void transp() {

for(int i=0; i<rows; i++) {

for(int j=i; j<cols; j++) {

T tmp = mtx[i][j];

mtx[i][j] = mtx[j][i];

mtx[j][i] = tmp;

}

}

}

Остальные функции приведены в приложении А.

Функционирование программы показано на рис. 2:[4]

Рисунок 2 – Интерфейс программы

ЗАКЛЮЧЕНИЕ

В наше время, когда усиливается связь между миром коммерции и миром разработки программного обеспечения, и корпорации тратят много усилий
на планирование бизнеса, ощущается необходимость в соответствии абстрактных бизнес процессов их программным реализациям. К сожалению, большинство языков программирования реально не имеют прямого пути для связи бизнес-логики и кода. Основной причиной этого является низкая функциональность языка, а именно отсутствие поддержки объектно-ориентированного подхода.

Например, сегодня многие программисты комментируют свои программы
для объяснения того, какие классы реализуют какой-либо абстрактный бизнес объект. C++ позволяет использовать типизированные, расширяемые метаданные, которые могут быть прикреплены к объекту, различные шаблонные классы
и лямбда-функции.

Разработчик может программно проверить атрибуты какого-либо элемента.

В процессе выполнения работы были получены и закреплены практические навыки разработки программ с использованием шаблонных классов при написании программы в среде визуального программирования Borland C++ Builder 6.0.

В процессе написания курсовой работы были реализованы следующие задачи:

– рассмотрены основные определения и классификацию языков программирования;

  • раскрыты основные понятия для языка С;
  • охарактеризованы основные определения принципы объектно-ориентированного программирования;
  • рассмотрены понятие шаблона класса в С++;
  • рассмотрено технологию создания программ с помощью шаблонных классов.

В процессе анализа вышеизложенной информации выявлены следующие достоинства объектно-ориентированного программирования:

  • удобность создания экземпляров класса разных типов данных;
  • гибкость в использовании;

интегрированность шаблонных классов в среде C++ Builder.

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1. Бобровский С. Самоучитель програмирования на языке C++ в среде Borland C++ Builder М.: ИНФРА-М, 2011.–251 c.

2. Культин Н.Б. С++ Buider в задачах и примерах – СПб.:БХВ-Петербург, 2012. – 336с.: ил.

3. Лаптев В.В. C++. Экспресс-курс . М.: 2014г.–322 с.

4. Послед Б.С. Borland C++ Builder 6. Разработка приложений баз. 2003г. -360ст.

5. Технология разработки приложения на языке С++. Методическое указание к лабораторным работам для студентов первого курса специальности 080801.65 “Прикладная информатика” (по областям)

6. Учебник по программированию в среде С++ Builder 5, Д. Холингворт, Б. Сворт, Д. Баттерфилд 865 с.

7. Б., Эллисон Ч. Философия С++. Практическое программирование. С.Петербург 2014г. 608 с.:ил.

8. М. Эллис, Б. Строуструп. Справочное руководство по языку C++ с комментариями: Пер. с англ. - Москва: Мир, 2012. 445с.

9. Стенли Б. Липпман. C++ для начинающих: Пер. с англ. 2тт. - Москва: Унитех; Рязань: Гэлион, 2012, 304-345с.

10. Бруно Бабэ. Просто и ясно о Borland C++: Пер. с англ. - Москва: БИНОМ, 2014. 400с.