Абстрактные типы данных: понятие класса и объекта

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

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

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

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

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

Рассмотрим пример создания структуры. Для этого прибегнем к специально зарезервированному в языке слову struct. Покажем как вывести в консоли дату date. Одновременно задействуем множество функций для обработки переменных такого типа:

#include <stdio.h>
struct date
{
int month; // месяц
int day; // день
int year; // год
};
void set_date(date* f, int d, int m, int y)
{
f->day = d;
f->month = m;
f->year = y;
}
void print_date(date* f)
{
printf(«%d.%d.%d», f->day, f->month, f->year);
}
int main()
{
date today;
set_date(&today, 2, 4, 2014);
print_date(&today);
getchar();
return 0;
}

Функции в данном примере никак не связаны с типами данных. Каждая функция в качестве аргументов оперирует указателями на элемент структуры.

Здесь функции представлены членами структуры. Они могут оперировать с данными, входящими в структуру.

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

#include <stdio.h>
struct date
{
int month; // месяц
int day; // день
int year; // год
void set_date(int d, int m, int y)
{
day = d; month = m; year = y;
}
void print_date(void);
};
void date::print_date(void)
{
printf(«%d.%d.%d», day, month, year);
}
int main()
{
date today;
today.set_date(2, 4, 2014);
today.print_date();
getchar();
return 0;
}

Обращение к функции-члену и данным-членам.

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

Можно использовать два способа для указания функций-членов:

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

В случае если включение функции-члена сделано в теле структуры, функция будет неявно встроенной.

(::
тип АТД::имя(список аргументов) {
тело функции-члена; }

тип — тип значения, которое возвращает функция-член
АТД — наименование абстрактного типа данных. Подразумевается метка структуры либо класса.
имя — наименование функции-члена

void date::print_date(void)
{ printf(«%d.%d.%d»,day, month, year);}

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

Права доступа.

Понятие структуры в языке С++ (этим он отличается от Си) делает возможным создавать структуры различного типа. Они могут быть общими, приватными, либо с ограниченным доступом:

public — общие;
private — частные;
protected — защищенные.

Ключевое слово protected имеет связь с концепцией «наследования». Наследование в С++ позволяет избежать дубликатов кода при описании классов. Ограничение доступа к части кода осуществляется посредством слова private. Объекты в этой группе доступны только функциям, у которых описана привилегия доступа к этим структурам. Как правило, эти функции и принадлежат этим группам.

Интерфейс для доступа к объекту структуры создается словом public.

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

Рассмотрим это на примере, отредактируем структуру date, скроем данные (применяем инкапсуляцию):

struct date
{
private:
int month, day, year;
public:
void set(int, int, int);
void print();
};

Нет комментариев

Оставить комментарий