Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекция 010

.pdf
Скачиваний:
9
Добавлен:
19.05.2015
Размер:
226.25 Кб
Скачать

Кафедра автоматизации технологических процессов Тверского государственного технического университета

Разработчик: доцент В. Г. Васильев

ЛЕКЦИЯ № 10 «Объектно-ориентрованное программирование»

по курсу «Структуры и алгоритмы обработки данных»

(для специальности «Управление в технических системах»)

СОДЕРЖАНИЕ

10.1Классы, данные и методы класса

10.2Типичные элементы класса

10.3Разграничение прав доступа

10.4Пример объявления и реализацию класса

10.5Правила для работы с членами-данными

10.6Правила для работы с функциями-членами класса

10.7Скрытый указатель this

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

Инкапсуляция - сведение кода и данных воедино в одном объекте, имеющем название класс.

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

Полиморфизм - дословный перевод с греческого "много форм". В частности , С++ полиморфизм реализуется с помощью виртуальных функций, которые позволяют в рамках всей иерархии классов иметь несколько версий одной и той же функции. Решение о том, какая именно версия должна выполняться в данный момент, определяется на этапе выполнения программы и носит название позднего связывания.

Инкапсуляция

Основное отличие С++ от С состоит в том, что в С++ имеются типы данных, которые называются классами. С точки зрения языка С классы в С++ - это структуры, в которых вместе с данными определяются функции. Это и есть инкапсуляция в терминах ООП.

10.1 Классы, данные и методы класса

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

Данные класса - это то, что класс знает. Функции-члены (методы) класса - это то, что класс делает.

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

Резюме

Класс = данные + функция (методы) для работы с ними. Инкапсуляция – слияние данных и функций, работающих с этими данными. Говорят, что класс инкапсулирует задачу.

10.2. Типичные элементы класса

Класс имеет следующие характерные элементы:

1. Члены данные,

2Члены функции (методы)

3Средства контроля доступа

4Конструкторы

5Деструкторы

6Специальный скрытый указатель this.

Класс, как и структура, должен быть предварительно объявлен. Синтаксис определения класса подобен синтаксису определения структуры и объединения в языке С.

Для объявления класса зарезервировано служебное слово class.

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

{

};

Структура в языке С++ является классом, все члены которого по умолчанию являются открытыми. Описание класса обычно помещают в .h- файл, а реализацию в .cpp-файлах.

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

Class Cl

{

};

void main ()

{

Cl a, *ptr, array[2];

}

10.3. Разграничение прав доступа

Члены класса могут иметь 3 уровня (режима) доступа. private: - закрытый;

public: - открытый; protected: - защищённый.

1.Public (открытый). Предназначен для объявлений, которые доступны для внешнего использования. Это открытый интерфейс класса.

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

3.Protected (защищенный). Cодержит объявления, доступные только для потомков объявляемого класса. Как и в случае закрытых элементов, можно скрыть детали реализации защищенных элементов от конечного пользователя. Однако, в отличие от закрытых членов класса, защищенные элементы доступны для программистов, которые захотят производить от этого класса производные классы, причем не требуется, чтобы производные классы объявлялись в этом же модуле.

В С++ Builder имеется недокументированный режим __published:,

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

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

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

Открытая часть класса (public) предназначена для обеспечения интерфейса объекта с программой.

Доступ к открытым членам объекта некоторого класса осуществляется при помощи операторов точка (.) и стрелка ( ->).

Функция может быть помещена внутрь определения класса. Такая функция называется подставляемой (inline) и может быть вынесена в файл реализации класса (cpp).

:: оператором привязки компилятору сообщается, к какому классу принадлежит данная фукция.

Функцию можно сделать подставляемой. Для этого при ее определении необходимо явно описать ее как inline. К примеру

inline int DataClass :: func ()

{

}

10.4.Рассмотрим пример объявления и реализацию класса

//Решение квадратного уравнения

#include <vcl.h> #include <conio.h> #include <math.h> #include <stdio.h> #pragma hdrstop

class Solve_qe

{

private: double a,b,c; public: double x1,x2; int solve(void);

Solve_qe( double a,double b,double c); Solve_qe( ){};

~Solve_qe();

double Get_a () {return a;} double Get_b ();

};

inline double Solve_qe:: Get_b ()

{

return b;

}

Solve_qe::Solve_qe( double _a, double _b, double _c)

{

a= _a; b= _b; c= _c;

}

Solve_qe::~Solve_qe()

{

printf("\nFINISH!");

}

int Solve_qe::solve(void)

{

double D;

D= b*b-4.0*a*c;

if ( D < 0.0) return -1; D = sqrt(D);

x1 = (-b+D)/(2.0*a);

x2 = (-b-D)/(2.0*a);

return 0;

}

#pragma argsused

int main(int argc, char* argv[])

{

{

Solve_qe qe1(1.0,-2.0, 1.0), *ptr, mas[2];

printf ("a =%lf\n",qe1.Get_a()) ; qe1.solve();

printf ("\n x1= %lf x2= %lf",qe1.x1,qe1.x2) ;

ptr = &qe1; ptr->solve();

printf ("\n x1= %lf x2= %lf",ptr->x1,ptr->x2) ;

Solve_qe *qe = new Solve_qe(1.0,-2.0, 1.0); qe->solve();

printf ("\n x1= %lf x2= %lf",qe->x1,qe->x2) ; delete qe;

}

getch(); return 0;

}

Результат работы программы будет выглядеть так.

a =1.000000

x1= 1.000000 x2= 1.000000 x1= 1.000000 x2= 1.000000 x1= 1.000000 x2= 1.000000

FINISH!

FINISH!

FINISH!

FINISH!

Вопрос: почему 4 раза FINISH?

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

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

Get_x().

10.5.Правила для работы с членами-данными

1.Не делайте все члены-данные открытыми – повысится надёжность программы

2.Используйте функции для обращения к закрытым членам-данным, если они должны быть доступны (используйте функции типа Set_x, Get_x)

3.Инициализируйте все члены-данные либо в списке инициализаторов, либо в теле конструктора.

4.Контролируйте значение присваиваемых закрытых членов-данных с

помощью

функций, чтобы

избежать неправильного ввода. Обычно

функция,

контролирующая

правильность ввода данных помещают в

закрытую часть класса (private).

5. Не забывайте уничтожать члены-данные, размещённые в памяти динамически. Для этого обычно используется деструктор (специальный метод класса)

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

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

Защищённые функции доступны только для тех классов, которые являются производными данного класса. Доступ к ним извне невозможен.

Функции-члены класса могут быть объявлены внутри тела класса, либо вынесены в отдельный модуль. Функция, объявленная внутри тела класса, является автоматически подставляемой. Это означает, что они подставляются в код программы. Это повышает быстродействие программы, но увеличивает размер кода. Допускается для таких функций применение лишь простейших операторов типа “+”, ”-”, ”*”, ”/”. Если реализация функций выносится за пределы класса, то в таком случае для них ограничений нет, при этом привязка функций к классу осуществляется при помощи оператора ::

10.6.Правила для работы с функциями-членами класса

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

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

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

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

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

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

Конструктор копирования предназначен для создания объектов данного класса путем копирования данных из другого, уже существующего объекта этого класса. Такие конструкторы особенно целесообразны для создания копий объектов, которые моделируют динамические структуры данных. Однако, по умолчанию компилятор создает так называемые конструкторы поверхностного копирования (shallow copy constructors), которые копируют только члены данных. Поэтому если какие-то члены данных содержат указатели, сами данные не будут копироваться. Для реализации "глубокого" копирования в код конструктора надо включить соответствующие инструкции.

Пример объявления и реализации конструктора:

Class MyClass

{

public:

MyClass ( void) ;

private: int A;

};

MyClass :: MyClass ( void) {А = 0; }

В этом примере объявлен конструктор MyClass без параметров, который при создании объекта задает начальное значение поля А равным

0.

Правила:

1. Ограничений на количество конструкторов для класса не существует.

2.Если конструкторов несколько, то все они должны отличаться количеством и типом формальных параметров.

3.Для конструктора не указывается тип возвращаемого значения

(даже void).

4.Имя конструктора должно в точности совпадать с именем класса.

Деструктор - специальная функция, которая автоматически вызывается перед уничтожением объекта. Обычно деструкторы выполняют операции, обратные тем, что выполняли соответствующие конструкторы. Если вы создали объект класса файл, то в деструкторе этот файл, вероятно, будет закрываться. Если конструктор класса выделяет динамическую память для массива данных (с помощью оператора new), то деструктор, вероятно, освободит выделенную память (с помощью оператора delete) и т.п. Деструктор не имеет параметров и может быть объявлен виртуальным. Если класс не содержит объявления деструктора, компилятор автоматически создаст его. Как и для конструктора, в деструкторе не указывается возвращаемый тип. Класс может иметь не более 1 деструктора. Наличие деструктора не обязательно. Имя деструктора образуется из имени класса с добавлением символа “~”.

Например:

Class MyClass

{

public:

~ MyClass ( ) ; // деструктор класса

};

// Пример класса для работы с курсором class Save_cursor

{

private:

TCursor save_cursor; public: Save_cursor()

{

save_cursor = Screen->Cursor; Screen->Cursor = crHourGlass;

}

~Save_cursor()

{

Screen->Cursor = save_cursor;

}

};

void __fastcall TForm1::Panel1Click(TObject *Sender)

{

{

Save_cursor *current = new Save_cursor();

for ( int i = 0; i < 100000; i ++) for ( int j = 0; j < 10000; j ++)

{

// чтодолго вычисляем

}

delete current;

}

return ;

}

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

Резюме

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

Имеют имя, идентичное имени своего класса.

Не имеют возвращаемого значения.

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

Автоматически генерируются компилятором как public, если не были вами объявлены иначе.

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

Могут содержать неявные обращения к операторам new и delete, если объект требует выделения и уничтожения динамической памяти.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]