Абстрактные типы данных

Язык C++ / Абстрактные типы данных

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

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

Рассмотрим реализацию понятия даты с использованием 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;
}
Функции-члены и данные-члены

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

В терминологии объектно-ориентированного программирования функция-член называется методом.

Определение функций-членов может осуществляться двумя способами:

  • описание функции непосредственно при описании структуры;
  • описание функции вне структуры.

Функции-члены, которые определены внутри структуры, являются неявно встроенными (inline). Как правило, только короткие, часто используемые функции-члены, должны определяться внутри структуры:

void set(int m, int d, int y) {month = m; day = d; year = y;};

Поскольку разные структуры могут иметь функции-члены с одинаковыми именами, при определении функции члена необходимо указывать имя структуры, связывая их с помощью оператора разрешения  контекста ::

тип АТД::имя(список аргументов) {
тело функции-члена; }
  • тип - тип возвращаемого значения функции-члена
  • АТД - имя абстрактного типа данных (имя структуры или класса)
  • имя - имя функции-члена
void date::print_date(void)
{ printf("%d.%d.%d",day, month, year);}
В функции-члене имена членов могут использоваться без явной ссылки на объект. В этом случае имя относится к члену того объекта, для которого функция была вызвана.

Функции-члены, одной и той же структуры могут быть полиморфными, то есть перегруженными.

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

Концепция структуры в языке С++ (в отличие от Си) позволяет членам структуры быть общими, частными или защищенными:
public – общие;
private – частные;
protected – защищенные.

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

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

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

Назад


Назад: Язык C++

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *