Объектно-ориентированное программирование учебное пособие



страница4/15
Дата17.04.2013
Размер1.64 Mb.
ТипУчебное пособие
1   2   3   4   5   6   7   8   9   ...   15

2.4. Конструкторы и деструкторы
Создание объекта некоторого класса может быть достаточно сложной процедурой. Поэтому в С++ предусмотрены возможности явного описания процедур создания и уничтожения объектов данного класса. Процедуры создания объектов называются- конструкторами, а уничтожения- деструкторами. Конструкторы автоматически вызываются при описании объекта, а деструкторы- при выходе из блока, в котором этот объект был описан. Конструкторы в С++ имеют имена, совпадающие с именем класса, а различаются между собой аргументами. Деструктор может быть только один и имеет имя, совпадающее с именем класса, которому предшествует символ “~”. И конструкторы и деструкторы не могут иметь описания типа.

Обратимся к ПРИМЕРУ 3, где мы описывали кольцевой буфер. Там нам нужна была функция init() для того, чтобы проанализировать индексы источника и приемника. Эта функция обязательно должна была вызываться для каждой создаваемой переменной этого типа. Если теперь мы преобразуем структуру C_Buffer в класс, то логично будет переделать функцию init в конструктор. Это пример, когда конструктор просто необходим при описании класса. Более редкий случай - когда необходимо применение деструктора. Деструктор нужен, например, для освобождения динамической памяти, занятой объектом.
Например, описание конструктора класса _3d:

Class _3d{

_3d(double &x,double &y,double &z){ x=X,Y=Y,z=Z;}

_3d(_3d&a){x=a.x;y=a.y;z=a.z;}

};
Если необходимые конструкторы или деструктор для класса не описаны, то транслятор создает их сам. Вызов конкретного конструктора для создаваемого объекта происходит в зависимости от аргументов, которые могут быть указаны в круглых скобках после имени создаваемого объекта, например: _3dA(0.0,1.0,0.0) , B;

Здесь для объекта А будет вызван описанный нами конструктор

_3d(double &x,double &y,double &z)

, а для объекта B - созданный транслятором _3d().

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

ПРИМЕР 4

Создать буфер значительного объема.
Необходимо изменить описание класса C_Buffer так, чтобы можно было задавать объем буфера при его объявлении. В состав класса вводится дополнительное поле - длина буфера. Эта переменная подставляется везде вместо цифры 1024. Кроме того, вводится конструктор, который размещает массив ptr, и деструктор, который его освобождает.

class C_Buffer{

public

double *ptr;

int dest,scr;

int len;

C_Buffer(int len=1024);

Cbuffer(){if ptr!=null) free(ptr);

void add(double a);

double get();

int used();

int free();

};

C_Buffer::C_Buffer(int _len){

len=_len;

dest=src=0;

ptr=(double*)malloc(len* sizeof(double));

if(ptr==null)len=0;

}

void C_Buffer::get(double &a){

if(++src:=len)return ptr[src-1];

src=0;

return ptr[len-1];

};

int C_Buffer::used(){

int n=dest-src;

if(n>=0)return n;

else return n+len;

};

int C_Buffer::free(){

int n=src-dest;

if(n>0) return n;

else return n+len;

};
2.5. Правила доступности членов класса
При описании класса можно определять доступность членов класса для “чужих” функций. Вообще, в ООП считается хорошим тоном задавать все данные и служебные методы описываемого класса для доступа “извне”.

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

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

Другое слово PROTECTED- определяет, что члены класса доступны только дружественным функциям и классам, а также классам- наследникам данного класса.

Слово PRIVATE ограничивает круг “посвященных “ только дружественными функциями и классами.

Дружественные функции и классы - это функции и классы, упомянутые внутри описания класса с описателем FRIEND. Это слово ставиться самым первым в описании такой функции или класса.
ПРИМЕР 5

Ограничить доступ к членам класса C_Buffer так, как описано выше.
class C_Buffer{

protected:

double *ptr;

int dest,scr;

int len;

public:

C_Buffer(int len=1024);

_C_Buffer(){if ptr!=null) free(ptr);};

void add(double a);

double get();

int used();

int free();

int length(){return len)}

};

Метод length() позволяет проверить размещение массива.

2.6. Механизм наследования
Наследование заключается в том, что для вновь издаваемого класса мы можем указать классы, от которых он наследует их данные и методы. Такие классы мы будем называть предками, или порождающими классами, а новый класс- наследником, или порождаемым классом. Как правило, порождаемый класс имеет лишь одного предка. Иногда идеология задачи требует создания мощного дерева иерархии классов. Механизм наследования хорош отнюдь не тем, что он позволяет не описывать наследуемых членов класса. Дело в том, что транслятор выполняет скрытое преобразование типов “сверху-вниз”, то есть объект - наследник “сходит” за своего родителя. Иначе говоря, функции, работающие с объектами класса-предка, будут с тем же успехом работать и с объектами класса-наследника. При этом ”наследники” ведут себя аналогично “предкам”.

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

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

Вот пример описания класса coord:
class coord:public _3d{

public:

_3d x,y,z;

};
Здесь описан класс-наследник класса _3d. Слово public перед именем класса-предка говорит о том, что общедоступные члены предка, наследуемые порождаемым классом, также общедоступны. Членами класса coord являются действительные x,y,z, координаты центра (наследуемые) и три вектора X,Y,Z, задающие направление осей в пространстве. Объект этого класса может работать и как вектор. В этом случае он представляет собой положение центра системы координат.
ПРИМЕР 6

Используя класс BASE_List, приведенный ниже, опишите класс DoubleList, реализующий список, из действительных чисел.
Рассмотрим абстрактный класс BASE_List. Этот класс реализует двунаправленный линейный список. Список - это последовательность объектов некоторого класса, называемых его элементами. В любой момент времени доступно не более одного элемента списка. Доступ к другим элементам можно получить, последовательно перемещаясь от одного элемента к другому, к концу списка или к его началу. При этом возможны три особых состояния: список пуст , доступный элемент вначале списка и доступный элемент в конце списка.

Возможна вставка нового элемента перед доступным элементом или после него. Для этого служит метод: ins(int b, int before);

Где l- длина вставляемого элемента, before- указывает на то, что элемент должен вставляться перед доступным, если before отлично от нуля, и за ним - если равно. Вставляемый элемент становится текущим. Доступный элемент можно удалить: для этого служит метод del();. При этом становится доступным следующий к концу элемент (если его нет, то предыдущий).

Для перемещения одного элемента к другому используются операторы: ”++”- от начала к концу, ”- -“ - от конца к началу. Метод void*object(); возвращает адрес текущего элемента.

Решение заключается в том что, чтобы сделать более простым доступ к текущему элементу и упростить вставку.
Class DoubleList:virtual public Bas_List{

Public;

Int ins(int befr=1){

Return Base_List::ins(sizeof(TYPE),befr);

}

double&operator*(){

return*((double*)object());

}};
2.7. Виртуальные методы
Как же быть, если мы хотим, чтобы “наследник” вел себя отлично от “предка”, при этом сохраняя свойства совместимости с ним? На этот случай существуют виртуальные методы.

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

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

В этом случае описывается базовый класс, для которого описывается виртуальные методы А. Как правило, методы А не конкретизируются (ставятся заглушки). После этого описываются методы Б, использующие методы А базового класса. Затем описываются классы, в которых методы А конкретизируются.

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

Проиллюстрируем все это на примере графических объектов. Опишем класс GraphicsObject. Это класс имеет методы Build- построить, Display- показать, Hid- скрыть, Move- переместить. Идея этого класса заключается в том, чтобы можно было перемещать графическое изображение по экрану не измения его содержимого.

Метод Display запоминает изображение в некоторой области памяти и вызывает метод Build, который в этой области строит новое изображение. Метод Hid скрывает изображение, построенное методом Build, восстанавливая то изображение, которое запомнил метод Display. Наконец, метод Move вызывает метод Hid, чтобы скрыть старое изображение, и метод Display, чтобы построить его на новом месте.
Объявим метод Build виртуальным. Опишем теперь двух потомков класса GraphicsObject- Circle- имеет метод Build, который строит окружность. Второй- Rectangle- имеет метод Build, который строит прямоугольник.

Программа, реализующая все это, выглядит так:

Circle A;

Rectangle B;
Если мы объявим так, то вызывая методы Display, Hid и Movе для объекта А, мы будем работать с кругом, а для объекта В - с прямоугольником.
class GraphicsObject{

protected:

int _x,_y;

void *image;

public:

void Display(int x,int y);

virtual void Build(int x, int y);

void Hid();

void Move(int x, int y);

};

classCircle:virtual public GraphicsObject{

virtual void Build(int x,int y); //строит кружок

};

class Rectangle:virtual public GraphicsObject{

virtual void Build(int x, int y); // строит прямоугольник

};
Если бы метод Build не был объявлен виртуальным, то при вызове А.Display вызывался бы метод: GraphicsObject::Build(int,int);

Но поскольку Build виртуальный, то вызывается Circle::Build(int,int);

Как же реализуется механизм виртуальных методов? Каждый объект, помимо полей данных, описанных для данного класса, содержит ссылку на таблицу адресов виртуальных методов своего класса. При вызове виртуального метода его адрес извлекается из соответствующей данному объекту таблицы - таким образом вызывается “то, что надо”. Объекты “таскают” свои виртуальные методы с собой.
3. История развития Турбо - Паскаля
Windows и Турбо - Паскаль появились одновременно, в 1983 году, однако их пути не пересекались до 1991. По сравнению с версией Windows 3.0 , ранние версии были медленными, со слабыми характеристиками и машинно-зависимыми. Однако Турбо Паскаль сразу же завоевал уважение и признание программистов не только своей стоимостью 50$ (а Windows - 500$), но и своими возможностями. Паскаль 1984 года - это дискета 360К и работа на машинах с самыми минимальными возможностями.

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

Однако программирование Windows программ было все еще трудным делом, так как шла постоянная модернизация Windows (в 1993 году была выпущена последняя версия от версии W0.54).

Турбо Паскаль для Windows соединяет объектно-ориентированное расширение, появившееся в Турбо Паскале 5.5, с Windows API (Application Program Interface). С появлением Паскаля для Windows становится значительно быстрее и проще программировать приложения под Windows, так как отпала необходимость знать внутренности Windows , а знать только программирование. Турбо Паскаль для Windows содержит все, что вам необходимо для написания любой программы для Windows. К этому моменту Турбо Паскаль имеет уже мало общего с первой версией. Сейчас это значительный программный продукт с отличной средой разработки и многочисленными приложениями, упрощающие процесс разработки программ любой сложности.

Итак, первым вариантом объектно-ориентированного языка Паскаль стала версия 5.5 (запущенная в 1989). В этой версии появились ключевые слова Object, Constructor, Destructor и Virtual.

Автономный и удобный отладчик Turbo Debugger был расширен средствами работы с объектами - в него даже была включена программа просмотра иерархии объектов и способность вызывать объектные методы. Нельзя сказать, что жизнь Турбо Паскаля была безбедной, немного ранее фирма Microsoft выпустила Quick Pascal с собственным набором объектно-ориентированных расширений и с ценой ниже, чем предлагал Borland за Турбо Паскаль. Были введены: многооконный мышиный интерфейс, и многие удобные для программиста элементы, такие как измененный цвет комментариев и др. Однако, существенное отличие объектно-ориентированных расширений от общепринятых в С++ и в Турбо Паскале достаточно быстро устранили Quick Pascal с рынка. К настоящему времени, несмотря на существенные изменения, программный продукт фирмы Microsoft не пользуется спросом.

Первые шаги объектно-ориентированного программирования были сложны. Отсутствие литературы, доступных примеров не располагали к использованию объектно-ориентированного программирования. Вскоре фирма Turbo Power Software выпустила библиотеку программ Object professional ,и объектно-ориентированное программирование стало неожиданно простым. Этот продукт содержит почти все мыслимые объекты, окна, меню, списки выбора, списки каталогов, массивы более 64К, резидентные модули и др. Эти объекты написаны так, что пользователи могут легко их изменять и расширять.

Шестая версия Турбо Паскаль появилась в 1990 году. Это уже полностью интегрированная среда, совмещенная с библиотекой Turbo Vission. Немного о Turbo Vission - событийно управляемом приложении. Вам не нужно начинать писать приложения, использующее Turbo Vission, с нуля, вам нужно просто выбрать из библиотеки соответствующий модуль и надстроить соответствующим образом. После этого программы могут считаться скорее событийно управляемыми, чем процедурными.

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

Событийно- управляемая программа, напротив, кажется почти хаотической. Телом такой программы является цикл наблюдения за входными действиями, такими как нажатие кнопок на клавиатуре или щелчок кнопкой мыши. Когда одно из таких действий происходит, программа переводит его во внутренний код события, после чего программа либо реагирует на событие и удаляет его из системы, либо передает его другому объекту. Это продолжается до тех пор, пока событие не обработано полностью или пока очередь сообщений, порожденных этим событием, не опустеет. Имеются такие события, которые передают всем объектам, и события, которые вызывают передачу сообщения от одного определенного объекта к другому. Написание событийно-управляемых программ включает создание объектов и наделение их способностью реагировать на соответствующие события. Это очень похоже на процесс создания программы для работы в среде Windows.

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

Дополнительные языковые возможности являются результатом адаптации компилятора для Windows, а библиотека Object Windows (OWL) обеспечивает ясную, объектно-ориентированную среду, которая избавляет программиста от необходимости прямого обращения к функциям Windows API.

Программы, написанные на Турбо Паскале 6.0, могут быть преобразованы для Windows простой заменой Dos приложений на Windows приложения. Однако еще остались сложности разработки Windows программ. Версия под номером 7 немного расширила возможности Турбо Паскаля, но не добавила принципиально нового.

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

Рассмотрим теперь объектно-ориентированные возможности Турбо Паскаля:

1   2   3   4   5   6   7   8   9   ...   15

Похожие:

Объектно-ориентированное программирование учебное пособие icon13. Основные принципы Объектно-Ориентированного Программирования (ооп) Объектно-Ориентированное Программирование
Объектно-Ориентированное Программирование это методология программирования, которая основана на представлении программы в виде совокупности...
Объектно-ориентированное программирование учебное пособие iconОбъектно-ориентированное программирование на языке Delphi
Методическое пособие предназначено для изучения основ объектно-ориентированного языка программирования Delphi (ооп) без ориентации...
Объектно-ориентированное программирование учебное пособие iconОбъектно-ориентированное программирование

Объектно-ориентированное программирование учебное пособие iconВизуальное объектно-ориентированное программирование. Графический интерфейс: форма и управляющие элементы

Объектно-ориентированное программирование учебное пособие iconСоздание web-сайтов, разработка программного обеспечения, объектно-ориентированное программирование, проектирование баз данных

Объектно-ориентированное программирование учебное пособие iconИнтегрированная среда разработки языка Visual Basic
...
Объектно-ориентированное программирование учебное пособие iconКурс: Объектно-ориентированное программирование
Напишите программу для общения через Internet. Программа должна состоять из двух частей: сервер и клиент. Сервер стартует в качестве...
Объектно-ориентированное программирование учебное пособие iconПрограммирование простых типов данных
Учебное пособие предназначено для студентов физического факультета, изучающих курс "Программирование и вычислительная физика"
Объектно-ориентированное программирование учебное пособие iconЗадание к лабораторным работам по курсу “Объектно-ориентированное программирование”
Разработать структуру элементов данных класса в виде динамической структуры данных (динамический массив, список, массив указателей)....
Объектно-ориентированное программирование учебное пособие iconУчебное пособие Уфа 2006 удк 519. 8 Б 19 ббк 22. 1: 22. 18 (Я7)
Бакусова С. М. Математика. Часть Математическое программирование / Учебное пособие. Уфа: ООО полиграфстудия «Оптима», 2006. – 71...
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org