Смекни!
smekni.com

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

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

Определения:

ANSI –American NationalStandards Institute- НациональныйИнститутСтандартизацииСША

ISO -International Organizationfor Standardization - Международнаяорганизацияпо стандартизации

Цельразвития языковпрограммирования- более рациональнаяразработкаПП.

Схемаразвития:

Кодыпроцессорааassembler аязыкивысокого уровня(ЯВУ)
Сначалаиз истории:

Приразработкепроцессоров(П)/микропроцессоров– для каждогоП разрабатываетсянабор команд,полный наборнасчитывает~150 команд: арифметика,логика, работас памятью, вводи вывод.

Командадля процессора– это цифровой код командыи операнд(операнды):

ячейкипамяти, регистры,порты ввода/вывода...

Кодыпроцессора–набор в цифровомкоде командпроцессораи их параметров,например, команды:занесениезначения нарегистр, выводс регистра поадресу памяти,сложение, чтениебайта из портаввода, записьбайта в портвывода
Именнокоды процессорасодержит исполняемыйфайл программыфайл (*.exe)

Разработкапрограмм вкодах былахарактернадля самых первыхВМ – это оченьнеудобно длячеловека-программиста.

Assembler– низкоуровневыйязыкпрограммирования,разработанныйдля конкретногопроцессора.

Assemblerиспользуетмнемоническоеобозначениекодов командпроцессораи переменныхпамяти, чтооблегчаетпроцесс программированияпо сравнениюс кодированием:
JUMP- переход, ADD- сложение, IN- ввод, OUT– вывод, и т.д.для всех командпроцессора.
Assemblerпозволяетиспользоватьвесь наборкоманд процессораи напрямуюработать срегистрами.
Используетсятам, где необходимавысокая эффективность:ядро ОС, драйверы,программы,работающиев реальномвремени.

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

Языкивысокого уровня– FORTRAN,ALGOL,COBOL,PL/I,ADA,Prolog,PASCAL,C,C++,Perl,JavaScript,ASP,PHP,Java,С#, SQL…

ЯВУне зависят отархитектурыкомпьютера,ориентированына эффективную разработкуПП, обеспечиваютбыструю разработкуи надежностьПО.
ЯВУ выполняютсяна любом компьютере,для которогореализованкомпиляторданного языкапрограммирования.

СредиЯВУ есть специализация:научные расчеты(FORTRAN),для обучения(ранний Basic,Pascal),экономическиерачеты (COBOL),работа с БД(dBase, FoxPRO,SQL),
целое семействосравнительномолодых языковдля Internet(JavaScript, ASP,PHP),
языки системногопрограммирования(ранний С, assembler’ы).
Некоторыеязыки считаютсяуниверсальными(поздний Pascal(Delphi), C/C++)

II.Развитие технологийразработкипрограмм
Схема:

Низкоуровневоепрограммирование(коды,Assembler’s) а
аПроцедурное/Cтруктурноепрограммирование(Algol, Pascal,C) а

аООП(C++,Object PASCAL, Java, C#…) а

а…(чтодальше?)

Вспоминаем,как обстоялодело с разработкойпрограмм в 60-е– 70-е годы,
технологическаяступеньканазывалась:

Процедурноепрограммирование

Основнаяидея – выделениечасти кода вотдельнуюпроцедуру(подпрограмму,функцию) (SUBROUTINEв FORTRAN, PROCEDUREи FUNCTIONв PASCAL).

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

Пример:
realsin(real x){

//здесь реализация

}

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

  • передачапараметровв процедуруи возврат значений,

  • рекурсивность,т.е. возможностьпроцедурывызывать самусебя (известнаязадача о Ханойскойбашне),

  • хранениеподпрограммв отдельныхбиблиотеках.


Далее,технологическаяступеньканачала 70-хгодов:
Структурноепрограммирование– основныеположения:
любуюпрограмму можнонаписать, пользуясьограниченнымнабором базовыхконструкций(здесьсхемы основныхконструкцийструктурногопрограммирования,Павловская,стр 39):

  • Последовательностьоператоров/блоков,

  • Ветвлениеили выбор if,if..else, swith-case

  • Циклы:с постусловием(do while),цикл с предусловием(while)


Каждаяиз базовыхконструкцийимеет одинвход и одинвыход.

Правильная”структурапрограммы(блока программы,подпрограммы),имеет один входи один выход.

Причем,любую программуможно и нужнописать безиспользованияоператора GoTo,который оченьзапутываетструктурупрограммы(аналог – командаперехода JMPв assembler).
Дляисключенияоператора GoToдостаточноприменятьбазовые конструкции“цикл” -не всегда этоудобно, но почтивсегда оправдано.

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

Следованиеэтим правилампри разработкепрограмм иозначало применение структурногоподхода кпрограммированию.Эти правилаограничивали“свободу”программистов(по сравнениюс assemblerи Fortran),но позволялиписать болеепонятные, простые,надежные программы.Улучшилсяконтроль надкодом, сталавозможна реализацияболее крупныхпроектов.

Набазе принциповструктурногопрограммирования(СП) был созданновый, элегантныйязык PASCAL(примерно1968 г, НиклаусВирт)
Проанализируемпрограммированиена PASCALс позиций СП.
БазовыеконструкцииСП внесены вязык: IF..[ELSE],CASE, WHILE,REPEAT..UNTIL.
Дляописания сложныхтипов данныхв языке естьмассивы, записи(RECORD),множества.

!Важно:

Структурапрограммы наPascalсостоит изразделов:

  • Uses -включениемодулей

  • Const– раздел констант

  • Type– описаниеновых типовданных (конструирование)

  • Var– объявление(выделениепамяти подреальные переменные)

  • Процедуры– реализуютавтономныефрагментывычислений

  • Главнаяпрограмма –Реализуетполный алгоритмрешения задачи.

PASCALжестко навязывалпрограммистамиспользованиестиля СП – этобыл переходна новый технологическийуровень в разработкепрограммобщего назначения(обработкаданных, научныерасчеты) –это был технологическийпрорыв.
Пожалуй,все последующиереализацииЯВУ, включаликонструкцииСП.
Разработкав стиле СП имеетнакладныерасходы (посравнению сassembler),код программыполучаетсябольше за счетизбыточныхпроверок вциклах и отсутсвияGoTo– это был основнойаргумент противниковСП (в основном,противникамибыли программистына assemblere).


Cтруктурноепрограммированиена С/С++

Напрошлом занятииговорили о СП,акцентировалиосновныеположения:
процедурноеП, П с исп. базовыхконструкцийСП, структурапрограммы наPASCAL.

Сложнеевсего следоватьстилю СП былона assembler’s.

ЯзыкС(Си) созданв конце 60-х - начале70-х для разработкисистемногоПО в рамкахпроекта ОС Unix(Деннис Ричи– один из авторов).

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

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

Сдает большуюсвободу действий,но требует отпрограммистабольшей самодисциплины.
Многие программистына assembler в 80-егоды перешлина C.

Внастоящее времяС универсальныйязык программированиядля разработкисистемногоПО (Unix и Windows),графическихинтерфейсов,сложного прикладногоПО (например,СУБД) - задач,где необходимаэффективностьвыполненияпрограмм.

С– распространен,компиляторыреализованыв большинствеОС.

Вкаждой реализацииUNIX естькомпиляторС/С++ как важнаячасть ОС.
C++являетсяобъектно-ориентированнымрасширениемязыка C.

Перваяшироко известнаяреализацияпринципов ООП– это описаниеязыка С++, начало80-х, авторомявляется БьярнеСтрауструп.

Кромекомпиляторовв каждой Unix-подобнойсистеме распространеныкомпиляторы
Borland C++ иMicrosoft C++ дляплатформыWindows,

В1997 г был принятмеждународныйстандарт ANSIC/C++ - итог20-тилетнегоразвития

Существующийстандарт ANSIC++ - это классическоеописание ООП.

Сейчасязык С++ являетсяязыком публикацийпо вопросамООП.

Практикумна С/С++:
ФактическиС++ содержит 2 языка:
ПолностьювключаетнизкоуровневыйСи, поддерживающийконструкцииСП, и, собственно,С++ (Си с классами)– язык объектно-ориентированногопрограммирования(ООП).

Мынаходимсясейчас натехнологическойступени структурногопрограммирования,поэтому начинаемс Си:

Знакомствос С, некоторыеконструкцииСП:


0.Программавыводит наэкран строку"Hello? World".

#include // подключениезаголовочногофайла, в которомописаны функцииi/o printf и getc

voidmain(){ // в программевсегда д.б. функцияmain, с нее начинаетсявыполнение

printf("Hello,World!");

getc();

}

1.//Комментарийдо конца строки

/*Комментариймного-

строчный.В С/С++ отличаютсяпрописные истрочные буквы.

*/


2.Операторныескобки {} задаютпрограммныйблок.


inti=5; // выделениепамяти и присваиваниезначения
{

inti=7;

..

if(i

}

if(i

//i внутри блокаи i вне блока –это разныепеременные


3.Цикл
for(int i=0; i

...

if(...)

break; // прервать цикл

}


if(i


4.Условный оператор

boolfOk=true; // true/false

inta, b=7;

...

fOk=(a==b);// вычисляетсялогическоезначение a==b иприсваивается

...

if(fOk){

//...выполняется,когда логическоевыражение true

}

else{

//...выполняется,когда логическоевыражение false

}


5.Цикл с постусловиеми выбор.


charc; // 1 byte

boolfOk;

do{ // Начало циклас постусловием

fOk=true;

printf(”Вылюбите программировать?\n”);

printf(”ОтветД/Н/?:”);

c=getc();


switch(c){ //

case‘Д’: printf(“Yes, sir”);

break;

case‘Н’: printf(“No”);

break;

case‘?’: printf(“Не знаю”);

break;

default:

printf(“*Ошибка,повторитеввод”);

fOk=false;

}

}

while(!fOk); // Конец циклас постусловием


6.Структуры.
Структурыв Си служат дляконструированияновых типовсложных данных
(Павловскаяс.67, Березин. с124)
structStudent{ // описаниенового типаданных Student

charName[51];

int Age;

charCourse;

charGroup[4]; // ПЭ2х
float Ball; //Average; // Средняя оценка

float S; // Стипендия

};//! Важно, в концеописания структурыставитсяточка-с-запятой;


StudentS1, S2; // Объявлениедвух переменных(выделениепамяти)

//Занесениезначений вэлементы структуры:

S1.Age=21;

S1.Kurs='2';

S1.S=550.5;

strcpy(S1.Name,"МистерХ."); // Копированиестроки в строкуструктуры


StudentPE21[50]; // Массив структур

strcpy(PE21[0].Name,"LadyY");

PE21[0].Age=17;

...

for(inti=0; i

if(PE21[i].Ball>=4.0)

PE21[i].S=400.0;

else

PE21[i].S=0.0;

}

Недостаткимассивов –жесткие рамки

Усложнения:
Повышеннаястипендия при4.5
Расчет среднегобала по группе

расчетсуммы стипендиипо группе


C/C++ Функция. Модуль.Проект. Заголовочныйфайл.


В Pascalесть понятия процедура ифункция.
Функция – это составнаячасть выражения,при вызове ейпередаютсяаргументы, авозвращаетсярезультат.

Процедура– выполняетчасть кода, необязательновозвращаетрезультат.


В С/С++нет процедур– только функции.Функции немогут бытьвложенными.

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


[]([списокпараметров]){

//тело функции(body)

return[];

}

Длякаждого параметрав списке указываетсятип.
Операторreturn прекращаетвыполнениефункции и возвращаетуправлениев точку вызова.
С помощью returnфункция можетвернуть вычисленноезначение.

Функция,которая невозвращаетзначения, должнабыть описанас типом void.


//Пример функциивычислениясреднего:

floatAverage(floata,floatb){

return(a+b)/2;

}

voidmain(){

//…

floatA=10.5, B=11.7, C=0.0;

C=Average(A,B); // Вызовфункции

//…

}

Любаяфункция (кромеmain)должна бытьописана в текстепрограммы домомента еевызова.

Вкачестве описанияможно применитьобъявлениепрототипа(прототип/заголовок/интерфейсфункции - синонимы),т.е. указатьимя функции,список передаваемыхпараметрови тип возвращаемогозначения, например:
floatAverage(floata,floatb);// Прототип функциивычислениясреднего


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

В С++допустимо иметьнесколькофункций с одинаковымименем и различающимисясписками параметров(это проявлениеполиморфизма),например:

int Summ(int A, int B); // вычислениесуммыдляint

floatSumm(float A, float B); // вычислениесуммыдляfloat


Впрограмме С/С++должна бытьфункция main(главная) – именноона вызываетсяпри запускепрограммы навыполнение:

intmain(intargc,char*argv[]){// ДЗ: разобратьсяс параметрамиmain

//intargc– число параметровв команднойстроке
//
char*argv[]– массив строк,где каждаястрока – параметриз
// команднойстроки.
argv[0]– имя программы.
//...
Здесьреализация,и возврат значения,например так:

if(fOk)

return0; //возвращениекода завершения

else

return-1; //возвращениекода завершения

}

Параметры функций.


Параметр,или аргумент – это значение,передаваемоев функцию.

Приразработкефункций используютсяимена параметров,которые являютсяформальными(условными).

В моментвызова функциией передаютсяфактические(реальные) значенияпараметров,которые подставляютсяна место формальных.

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


Припередаче параметрапо значениюсоздается егокопия в локальнойпеременнойи далее функцияработает с этойкопией.

Этонеудобно вследующихслучаях:

  • когдапередаетсябольшой массив,структура(создание копиипараметразанимает многовремени и памяти).

  • когданужно изменитьзначение параметравнутри функциии вернуть еговызывающейпрограмме(например, привводе структуры,при сортировкемассива и т.д.).


Припередаче параметрапо ссылке вфункцию передаетсятолько адресисходной переменной.

Изменениезначения параметраприводит кизменениюисходной переменной.


Передачапараметра поссылке подобнапередаче вкачестве параметрауказателя напеременную.


Примеры:


//1.Функция сохраняетзначения структурыв файле

boolSaveToFile(TStudentS){ // Это передачапараметра позначению,

//... // создаетсялокальная копияпараметра

FILE*outS;

outS=fopen(PathOutFile,"at");

//...

fprintf(outS,"%s %s \n",S.Name, strAge );

//...

fclose(outS);

returntrue;

}


//2.Функция читаетзначения изфайла в структуруи возвращаетввод

boolInputFromFile(TStudent&S){ // Это передачапараметра поссылке,

//... // иначе вводбудет потерян

FILE*inS;

inS=fopen(PathInFile,"rt");

scanf(inS,"%s",&S.Name);

//...

returntrue;

}


ДЗСамостоятельно:функции, параметры,возвращаемыезначения; функцияmain;
вкнига: Паловская,стр 73, Березин,стр. 108.


Модуль.
Модуль в С/С++
– это отдельнокомпилируемыйфайл, которыйможет содержать:описание типов,объявленийпеременныхи констант, кодфункций.
Имямодуля естьимя файла cрасширением*.cpp(*.c).

Оптимальныйразмер модуля,удобный дляразработкии отладки –200-400 строк текста.
Еслитекст программывелик, то егоделят на несколькомодулей и объединяютмодули в проект.

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


Здесьсхема модуляC++, сравнениесо структуройпрограммы наPascal

ПроектC/C++- это средстводля объединениямодулей в единуюпрограмму илибиблиотеку.Целью разработкипроекта можетбыть не толькопрограмма, нои библиотекафункций, библиотекаклассов.

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

В проектмогут подключатьсямодули в видеисходноготекста С++ (файлы*.cpp), в видеобъектногомодуля (файлы*.obj), в видебиблиотекфункций (файлы*.lib), и др...


В IDEBorland C++ естьсредства веденияпроекта: окнопроекта, пунктменю Project.

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

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


Заголовочныефайлы. ПрепроцессорС/С++.

Обычнодля модуляC/C++разрабатываетсязаголовочныйфайл, в которомописываютсяобщие константы,типы данных,и объявляютсяпрототипыфункций.
Заголовочныефайлы имеютрасширение*.hили *.hpp(от Header - заголовок).

Имязаголовочногофайла можетсовпадать илине совпадатьс именем модуля.


Примерзаголовочногофайла (Student.h)

//-----------------------------------------------------------------

#defineMIN_AGE12 // Константы,часто используютсятакие описания

#defineMAX_AGE 99


structTStudent {

//...Описание новоготипа данныхTStudent

};


boolInputDataStudent(TStudent* S); // Прототипыфункций

voidOutputDataStudent(TStudent* S);

intAverageAge();

//-----------------------------------------------------------------


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


#includeимязаголовочногофайла.h>


Препроцессорбыл разработандля языка C.

Онвыполняетсядо начала компиляциии производитобработкудиректив втексте модуля.

Например,на место #includeh>подставляетсясодержимоеэтого файла,

потексту программыпроизводитсязамена макросовиз #defineMIN_AGEна 12,и т. д.


СсистемойпрограммированияC/C++поставляетсямножествобиблиотек,содержащихпредопределенныеконстанты,макросы, функциии классы.
Библиотекипоставляютсявместе с заголовочнымифайлами. Заголовочныефайлы многихбиблиотекнаходятся вдиректории...\Include.
Текстзаголовочныхфайлов являетсясамой точнойдокументациейпо использованиюфункций, поставляемыхв библиотеках.а Значит,необходимоуметь анализироватьHeader-файлы:


Приложение:

//Пример заголовочногофайла (Student.h)

#ifndefSTUDENT_H

#defineSTUDENT_H


#defineMIN_AGE 12 //Константы,часто используютсятакие описания

#defineMAX_AGE 99

typedefstruct s{ // Описаниеновых типовданных

charName[20];

intAge;

//...

}TStudent;

boolInputDataStudent(TStudent* S); // Прототипыфункций

voidOutputDataStudent(TStudent* S);

intAverageAge();

#endif

//-----------------------------------------------------------


#include

#defineEOF (-1)/* End of file indicator */

#defineMAX(a,b) ((a>b)? a :b)// Макрос


Макросыненадежны, ихконтроль компиляторомограничен.

В С++ применениемакросов нерекомендовано,в этом нетнеобходимости,т.к. в базовыхконструкцияхязыка появилиськонстанты,шаблоны и inlineфункции.


Ввод/выводC/С++.

Ввод/вывод(Input/Output,I/O)– это операцииобмена даннымимежду программойи внешнимиустройствами.

Операцииввода/выводаинициируетпрограмма,поэтому:

  • ввод– перемещениеданных с внешнегоустройствав программу(в структуруданных в ОП)

  • вывод- перемещениеданных изпрограммы навнешнее устройство(в файл, на экран,на печать)

ОперацииAssembler:

IN:взять байт изпорта и поместитьв ОП

OUT:взять байт изОП и поместитьв порт

Потокии файлы

Файл(file) – этоспособ храненияинформациина физическомустройстве:
дисковыйфайл, МЛ, распечатка,вывод на дисплей– это все файлы.

Ввод/выводв программене должен зависетьот устройства,
Т.е.разработчикпрограммыопределяеттолько типопераций I/O(последовательныйдоступ, произвольныйдоступ), а устройствоопределяетсяпри операцииоткрытия файла.

Дляотделенияопераций ввода/выводав программеот физическогоустройствахранения файловв системахпрограммированияреализуетсясхема вв./выв.с промежуточнымзвеном:

functionI/Oв программеа

аstream(поток) а

аfile(файл на устройстве)

Поток(stream) – этоабстрактныйуровень взаимодействиямежду программойи физическимустройством.
Информациявыводитсяв поток (вводитсяиз потока) какпоследовательностьбайтов – символза символом.
В момент открытияпотока он связываетсяс файлом наконкретномустройстве.

ВСи (не в С++) дляэтого служитуправляющаяструктурапотока FILE.

(FILE,например, включаетбуфер дляпромежуточноговв/выв, указательна текущуюпозицию в буфере)(FILE описанас ,задание напрактику –ознакомиться)

Потокибывают буферизованные(блокированные)и небуферизованные(НЕблокированные).

Буферизованныепотоки выводанакапливаютинформациюв буфере передвыводом наустройство.

Буферизованныепотоки вводапроизводятопережающеечтение в буферпотока.

Буферизацияслужит дляоптимизациивв/вывода (размерсектора надиске 512 байт,кластер. Длявв/вывода даже1 байта необходимозаписать/перезаписатьсектор/кластер).

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

Дляпринудительноговывода приработе с буферизованнымипотоками естьспециальнаяоперация: fflush(...)– выравнивание,сброс на диск

Ввод/выводв С

Вописании языкаСи нет операцийввода/вывода,они реализованычерез функции.

Ключевыеслова в названияхфункций:

read/write– неформатированныйвв/вывод, сплошноймассив байт

get/put,

scan/print,

open/close

например:

printf,fprintf,sprintf- ключевыеслова используютсяс различнымипрефиксами– вывод в стандартныйпоток, выводв файл, выводв область памяти.


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

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

Что-товсе-равно нужнознать аДокументация(общее представление)а HelpаЗаголовочныйфайл

ПримерСи, вывод данныхструктуры втекстовый файл:


structStudent{

char*Name;

intAge;

};

StudentAS[43];

//...


FILE*outS;// Объявлениепотока


outS=fopen("D:\Data\Person.dat","wt"); // Открытиепотока,связываниесфайлом
//
режимwrite,text

for(inti=0; i

fprintf(outs,"%s,- ему%s лет\n",AS[i].Name, itoa(AS[i].Age) );

}


fclose(outS);

//--------------------------------


//--------------------------------

StudentP;

FILE*InP=fopen("Person.dat","rt"); // Открытиепотока,связываниеегосконкретным
//
файлом"Person.dat"

char*cAge[3];//Временнаяпеременая дляввода символьногочисла, соответств.Age

fscanf(InP,"%s%s", &P.Name, cAge);// Вводизфайлачерезпоток


//или

fgets(InP,P.Name);

fgetc(InP,cAge);


fclose(InP);//закрытие потокаи файла.


Ввод/выводв С++(начальныесведения)

ФункцииСи можно использоватьв С++.

ВС++ ввод/выводопределен черезбазовый наборклассов, поставляемыхс компилятором.

Следующиеклассы реализуютпотоки, ониобъявлены взаголовочномфайле :
ostream– поток длявывода

istream– поток дляввода

iostream- поток дляввода/вывода


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

Подробнеео переопределенииопераций вв/вывпоговоримпозже, когдабудем конструироватьклассы.А покапознакомимсясо стандартнымисредствами:


Cтандартныепотоки С++:

cin– стандартныйпоток ввода(консоль)

cout– стандартныйпоток вывода(консоль)

cerr– стандартныйпоток выводаошибок небуферизированный

clog– стандартныйпоток выводаошибок буферизированный

Стандартныепотоки объявлятьне надо.


Операцияввода из потока>> , операциявывода в поток(это двойныеугловые скобки)


Пример:

coutcout)

cin>>P.Name; // Ввод значенияс клавиатурычерез потокcin
// в переменнуюструктуры
P

coutn"P.Namen";

Дляосвоения темыввода/выводав С++ необходиморазобратьсяс переопределениемопераций ввода/выводадля классов(см. "Практическуюработу №2")

Потоковыеклассы, стандартныепотоки, файловыепотоки С++: Павловская,стр 265.


Схемыиерархии модулейв типичномпроекте программыобработкиданных.

Проект-проектирование.

Структурапроекта – составмодулей и ихвзаимодействие.


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

Здесьтипичная схемапрограммыобработкиданных:

Головноймодуль осуществляетобщее управлениеи последовательновызывает иконтролируетвыполнениеподчиненныхфункциональныхмодулей, например,в такой последовательности:

ВводданныхаОбработка аДиалог с операторомаСохранениеданных


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


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

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

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

Диалогс операторомведется по меренеобходимости.


Модульна этапе проектирования- это функциональнообособленыйфрагмент проекта,например: модульввода, модульобработки,головной модульпрограммы.

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


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


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


C/C++.Преобразованиепроекта изисходноготекста в исполняемыймодуль


Рассмотримпроцесс разработкипрограммы.

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


TextС/С++->PreProc-> Compile-> ObjectModule(*.obj)-> Link->EXEModule

Edit Library(*.lib)->

(*.c,*.cpp,*.h) ЯDebugЯ

(см.также Павловская,стр 17)

TextEditor– созданиетекста исходныхмодулей проектана языке программирования– "кодирование"("кодировщики"- жаргон) Кодированиюпредшествуетпроектирование..

Compile(compilation, компилятор,составитель)– производитконтроль текстапрограммы,выдает сообщенияоб ошибкахвремени компиляции– это начальныйпериод отладки.
Врезультатеуспешной компиляциииз текста исходногомодуля получаетсяобъектныймодуль.

Objectmodule(obj)– операторыисходноготекста программы,преобразованные во внутреннеемашинноепредставление– "код", инструкциипроцессора.
(формат кодаотличаетсядля каждойархитектуры).

Objсодержитоткомпилированныеоператоры языка+ вызовы функций.
Вызовыфункций внутриobjназываются“неразрешенныессылки”:

например,это вызовыбиблиотечныхфункций printf,scanf,…, или вызовыразработанныхранее функцийиз другогомодуля проекта.

Link– редакторсвязей, сборщикпрограммы -производитсборку исполняемогомодуля - executemodule, exe -из одного илинесколькихобъектныхмодулей и библиотек.

Присборке в ехе-модуль из библиотеки других obj-модулейпроекта заноситсякод функций,вызовы которыхуказаны в исходномтексте программы
– этот процессназывается“разрешениессылок”.

Далее*.ехезапускаетсяна выполнение,тестируется,отлаживается.


Замечанияпо стилю разработкии оформлениютекстов программ

Комментирование

Первойстрокй любогомодуля д.б.комментарийс указанием

//Автор, ПЭ21, ДВГТУ,ООП, dd.mm.yy

//Проект, назначениемодуля


Каждуюфункцию такжеследует предворятькомментарием,если ее код нетривиален.

Тестдля комментария– понятностьдля не посвященногов проблемуспециалиста.

Комментированиепрограмм –профессиональныйнавык.
Хорошийприем – сначаласоздаватьскелетный кодмодуля из текстовкомментариеви заголовковфункций с пустымблоком реализации(функции заглушки).

Фрагменттекста программы(строку), которыйуже не используется,а удалять ещежалко – можнозакомментровать.

Правилаименованияпеременных

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

TCar,TAutobus

InputFromFileToPerson

Разумноекомментированиеи выбор именпридает текстампрограммысвойствосамодокументированности.
Отступы каксредствоструктурированиятекстов:

Текстпрограммы легчеанализировать,когда он структурирован,разбит на блоки
Блокв программе– это фрагменттекста внутрифигурных скобок{…}.

Например:описание структуры,функция, телоцикла и др.
Любойвложенный вблок долженбыть сдвинутвправо на табуляцию(обычно от 2 до8 символов).

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

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

Комбинацияклавиш Ctrl+{> и Ctrl}> – позволяетконтролироватьблоки.

!Все безисключенияпрактическиеработы необходимооформлять поэтим правилам
(см.также Павловская,стр 102-114)

C/C++.Интегрированнаясреда разработкифирмы Borland
(Используетсяв С/С++ Builder и вDelphi)

IDE- Integrated Development Environment

IDEдля разныхплатформразработкиПО:
Borland:
средаturbo-vision -> Turbo Pascal, Turbo C, СУБДParadox
Delphi и Builder (VisualComponent Library) СУБДInterbase, JBuilder -> Borland Studio

MSVisual Studio
IBM Visual Age

Linux(?) (Emacs)

ОсновныекомпонентыIDE:

  • специализированныйредактор текстапрограмм(многодокументноеокно )

  • средстваведения проекта,состоящегоиз несколькихмодулей (окнопроекта)

  • системазапуска компилятора(пункт меню,комбинацияклавиш)

  • окнопросмотрасообщенийкомпиляции.

  • Help-система(!)

  • встроенныйотладчик (Debuger)

Атакже:

  • визуальныйконструкторформ

  • инспекторобъектов (ООП)

  • Classexplorer

  • Клиентдля работы сБД

  • Графическийредактор

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


ЦиклразработкиПО с точки зренияпрограммиста:
(?Начальнаяидея)

->Подготовкатекста программыв редакторе

-> Запусккомпилятора

->Возврат:Анализи исправлениеошибок

->Получениезагрузочногомодуля

->Выполнениезагрузочногомодуля

->Возврат:Анализи исправлениеошибок

->…и так далее


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


Непутать интегрированнуюсреду и компиляторязыка программирования!

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


СовременныеIDE предлагаюттакже визуальноеконструированиедля оконногоинтерфейсаи созданияскелетногокода программы.Пример: обработкасобытия нажатиякнопки.


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

Освоениесовременнойсреды программированиясравнимо посложности сосвоениемнового языкапрограммирования.

BorlandIDE – этосовременнаяпрофессиональнаясреда разработки,весьма сложнаяв освоении.


Началоработы в IDE:

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


Первоначальнобудем создаватьпрограммы,работающиев стиле DOS(WIN32) – текстовыйрежим консоли.Ихназывают такжеconsoleapplications.

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

Созданиепрограмм сграфическиминтерфейсомWindows – в перспективе,на следующейдсциплине.


Последовательностьдействий в IDEпо созданиюприложеняConsoleapplication:
МенюFile->New->ConsoleWizard- создание проекта(создаетсяскелетная схемапроекта, заготовкафункции main),далее
->Собственноразработкатекста программы

->Запускна компиляцию– выявлениеошибок – сначалапотребуетсохранитьфайлы
-> есликомпиляцияпроходит, то –> созданиезагрузочногомодуля (ЗМ)

–>выполнениеЗМ с возможностьюотладки.

Типыфайлов (расширения),создаваемыесистемой IDEв проекте:


*.cpp,*.h - исходныетексты программы,исходные модули;этим файламнеобходимообеспечитьмаксимальнуюзащиту.

*.bpr,*.bpg, *.bpf– файлы проектаи группы проектов; (желательносохранять, нопроект легкоможно собратьи заново изисходных модулей)

*.~cpp,*.~h *.~bpr - backupfiles (со знаком"тильда") –содержат копиюисходноготекста/проекта,предшествующую последнейкорректировке.

*.obj– объектныемодули, промежуточныйформат, создаютсякаждый раз прикомпиляцииисходных модулей(опция настройкиIntermediateoutput)

*.tds– временныйфайл отладчика,обычно этосамый большойфайл в проекте.

*.exe– загрузочныймодуль, исполняемыймодуль (опциянастройки Finaloutput)


Рекомендациипо управлениюфайлами проекта:


  1. Необходимообеспечитьсохранностьисходных файловпроекта *.cpp,*.h, *.bpr,*.bpg, *.bpf.
    Желательнорасполагатьфайлы каждогопроекта в отдельнойдиректории.
    Необходимохранить однуили более предыдущихверсий работы(для этого создаетсяспециальнаядиректорииархива, традиционноеназвание - BACUP).

  2. Желательноперенаправитьпромежуточныйвывод *.obj,и результирующийвывод *.tds,*.exe вовспомогательныедиректориина локальномдиске, т.е. несмешивать сисходнымитекстами:
    Project->Options->Directories->Intermediateoutput/Finaloutput
    Этифайлы желательноудалять позавершениисеанса работы.

  3. Присваивайтефайлам мнемоническизначимые имена- это помогаютподдерживатьпорядок в работе.
    Архивированиеи удалениефайлов рекомендуетсяделать по завершенииэтапа работ(занятия).


Отладкав интегрированнойсреде С++ Builder.


Цельотладки – локализацияи устранениеошибок, приводящихк неверномуфункционированиюпрограмм.

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


Примерыошибок:

  • Невыполняетсяусловие переходана ветвь алгоритма

  • Системноесообщение"Access denieded"при выполнениифункции ввода.

  • Открытиенесуществующегофайла на чтение.

  • Ит.д.


Чтоделать?

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


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


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

Затемустановитьконтрольнуюточку (breakpoint) до этогоместа.

Запуститьпрограмму, онаначнет выполнятьсяи остановитьсяна строке breakpoint.

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

Далеевозможно пошаговоевыполнениепрограммы снаблюдениемзначений переменныхдо возникновенияошибки.


Основныеприемы отладки:

  • Установкаконтрольныхточек и просмотрзначений переменных

  • Пошаговоевыполнениепрограммы ипросмотр значенийпеременных

  • Вставкаотладочногокода в программу– ловушка

  • Контрольнаяпечать, трассировка– давнее средствоотладки.


Современныесистемы разработкиимеют хорошиесредства отладки.

ВIDE C++Builerесть хорошийвстроенныйотладчик.


Некоторыеключевые словаи клавиши управления

InspectAlt+F5– наблюдениеза объектом(подробно)

Watсh - – наблюдениеза несколькимиобъектами

TraceintoF7– пошаговоевыполнениес переходомвнутрь функций

Stepower - F8– пошаговоевыполнение,включая вызовфункций


…РазвитиеС аС++ – переводитразработкуПП на современнуютехнологиюООП.


С++.Основы Объектно-ориентированногопрограммирования(ООП).
Введениев объектно-ориентированноепрограммирование.


C++являетсяобъектно-ориентированнымрасширениемязыка C.

Перваяшироко известнаяреализацияпринципов ООП– это описаниеязыка С++, БьярнеСтрауструп,начало 80-х.

Вкаждой реализацииUNIXесть компиляторС/С++ как составнаячасть ОС.
РаспространеныкомпиляторыBorland C++и Microsoft C++для платформыWindows,

В1997 г был принятмеждународныйстандарт ANSIC/C++- итог 20-тилетнегоразвития

Существующийстандарт ANSIC++- это классическоеописание ООП.

Сейчасязык С++ являетсяязыком публикацийпо вопросамООП.

_______

Итак,С++, ООП:


Мыуже хорошознаем работусо структурамиданных в Си,это наша отправнаяточка..

Асейчас познакомимсяс важными понятиямиООП в языкеС++: объект и класс.


!Основная идеяООП– размещение внутри одногообъектаструктурыданных и функцийобработки этихданных:


Объект= структураданных + функцийобработки этихданных;


Объект– определениеИвари Якобсона:
"Объект– сущность,способнаясохранять своесостояние иобеспечивающаянабор операцийдля проверкии изменениясостояния".


ВС++:

Новоепонятие class–служит дляопределенияновых типовобъектов.

(подобноструктуреstructTStudent,которая служитдля определениянового сложноготипа данных.


Объектомв С++ называютконкретныйэкземплярреализациикласса.

(Какпеременнаятипа TStructявляется экземпляромструктуры,который наполняетсяреальнымиданными)


classвключает поляи функции / свойстваи методы/ атрибуты иоперации– эти пары терминов,по терминологиипроцедурногопрограммирования,относятся кданным и функциямобработки этихданных.

classимеет разделы:

privateи protected– защищенные,недоступныеснаружи, и

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


Принципы,составляющиесуть ООП.

Рассмотримтри:

  • Инкапсуляция(Encapsulation –сокрытие,герметизациявнутри) – объединениеданных и кода+ защита от внешнеговмешательстваи неверногоиспользования.
    Реализациякласса можетбыть скрытав защищеннойобласти (private,protected),доступ к которойосуществляетсячерез интерфейсныеполя/функциипубличной(public)области.

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

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


Д.З.Павловская.Часть II.ООП (стр. 173). Основныеидеи, принципыООП.

Глава4. Классы (179). Глава5. Наследование(201).

Березин,стр.166.


Описаниекласса и объявлениеобъекта в языкеС++:

Примерконструированиякласса, подобногоструктуреTStudent


classTStudent{// Описание класса

private:

charName[20];//... описаниевнутренних,недоступныхснаружи,

intAge; // методов исвойств

public:

//...описание интерфейса,т.е. доступныхметодов и свойствкласса

TStudent(...){...};// Конструктор,обэтомпозднее

voidSetAge(int a){Age=a;};

voidSetName(char* n){strcpy(Name,n);};

char*GetName(){ return &Name[0];);

int GetAge(){ return Age;);

voidInputFromConsole();

voidOutToConsole();

boolSaveToFile(char* PathFile); // толькопрототипыметодов,

boolGetFromFile(FILE*inStud); // реализациягде-то позднее

};


TStudentS1; // Объявлениеобъекта (конкретногоэкземпляракласса)

//Работа с объектомчерез вызовметодов

S1.SetName("ИльяМуромец");

S1.SetAge(33);

S1.SaveToFile("C:\Temp\Student.dat");


TStudentAS[43];// Объявлениемассива объектов

AS[0].InputFromConsole();

AS[0].SaveToFile();


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

Можноработать cобъектом толькочерез функциии переменныеиз разделаpublic,т.е. через интерфейс.

S1.Age=18;// это попыткапрямого обращенияк полю из privateраздела,
//не пройдет,компиляторвыдаст ошибку.

Такойконтроль обеспечиваетпервый принципООП – инкапсуляцию–сокрытие изащиту механизмареализациикласса.


-------------------

Далееважные вопросыООП: классы и функции-членыкласса, конструкторыи деструкторы.


Классыи функции - членыкласса.


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

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


Функции,описанныевнутри разделовкласса (какполные функции,так и прототипы),называютсяmembers functions– функции-членыкласса/методыкласса.

Онимогут вызыватьсятолько черезобращение кобъекту этогокласса (аналогияс элементамиструктуры):

SaveToFile();//Неверно, неуказан объект,

//для котороговызываетсяметод

S1.SaveToFile();// Верно


Еслив описаниикласса указантолько прототипфункции, а реализациянаходится запределамикласса (описаниекласса в заголовочномфайле, а реализацияфункций-членовкласса в файле*.cpp),то необходимоуказывать имякласса и знак"::" :


voidOutToConsole(); // так был описанпрототип вклассе TStudent


voidTStudent::OutToConsole(){// А это реализацияв функции

printf("Name=%s\n",Name);

printf("Age=%d\n",Age);

}

-------------------------------------------------

Конструкторыи деструктор


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

Естьнеобходимостьинициализироватьобъекты классав момент создания(т.е. задаватьначальноесостояние).

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

Имяфункции-конструкторасовпадает сименем класса.
Конструкторыне возвращаютзначений.

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

Возможностьсоздать несколькоодноименныхфункций класса(методов) - этопроявлениеполиморфизмаООП


Примерыконструкторов:


classTDate{// Класс для работыс датой

...

public:

//Конструкторы,только прототипы,реализациив другом месте

TDate(intdd, int mm, int yy); //

TDate(int); // порядковыйномер дня отР.Х.

TDate(char*);// строка"dd.mm.yy"

TDate(); // текущая датапо компьютернымчасам

...

};

...

//Создание иинициализацияобъектов черезвызов конструкторов

TDatetoday(22, 11, 2002);

TDateApril1("01.04.2001");

TDatenow();


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


classTDate{

...

public:

TDate(intd=0,int m=0,int y=0); // поумолчаниювсезначения0

...

}

...

TDate::TDate(intd,int m,int y){

...

day=d?d:today.day;// если d==0, тоd=today.day


};


//?TDated=today;// возможнаинициализацияобъекта посредствомприсваивания


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

Имяфункции-деструкторасовпадает сименем классас добавлениемзнака ~ "тильда".
Деструкторыне возвращаютзначений.


Деструкторвызываетсяавтоматическипри выходеобъекта из зонывидимости.

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


Примердеструктора:

classX{

char*S;

public:

X(int);

~X();

};


X::X(intN){ // Конструктор

S=newchar[N]; // Динамическоевыделениепамяти

}

X::~X(){ // Деструктор

deleteS; // Освобождениединамическивыделеннойпамяти
}


XObj1(256);

X*pObj2=newX(125);//динамическоевыделениепамяти подобъект типаX


deletepObj2;// явный вызовдеструктора


Итоговыезамечания поконструкторами деструкторам:

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

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

  • Конструкторовможет бытьнесколько,деструкторвсегда один.

Прежде,чем идти дальше,необходимопоговоритьпро механизмраспределенияпамяти в программахна С/С++.


С/С++:Виды объектовв памяти и времяих жизни :


  • Автоматическийобъект: создаетсякаждый раз,когда его описаниевстречаетсяпри выполнениипрограммы, иуничтожаетсяпри выходе изобласти видимости(из блока).

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

  • Динамическийобъект: (объектв свободнойпамяти) создаетсяявно (программистом)с помощью операцииnewи удаляетсяявно с помощьюdelete,либо автоматическипри завершениипрограммы.


Подобъектом здесьпонимаетсяпеременная,массив, структура,объект класса.


Примеры:

//Статическаяпеременная:

staticchar*sPathData="C:\Temp\Test.dat";


//Автоматическаяпеременная,"живет" тольковнутри блока:

{

charaS[80];

//...

}


//Динамическисоздаваемаяпеременная,явное выделениепамяти

//и явное уничтожение:

char*pStr=newchar[80];

//...

deletepStr;
-------------------------------------------------


С++.Основы ООП. Наследованиеклассов.

Важнейшимсвойством ООПявляетсянаследование.

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

аМожносоздать новыйкласс на основесуществующегочерез наследование.

Исходныйкласс называют предок/родитель/базовыйкласс/parent,а новый класс- наследник/потомок/производныйкласс/derived/child.

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

Такстроится иерархияклассов – важноепонятие ООП.


Принеобходимостив производномклассе можноперекрыть(переопределить)свойства иметоды базовогокласса.


Примероммногоуровневойиерархии классовявляется VCLот фирмы Borland.

Формазаписи заголовкапроизводногокласса:


class: {}


classB: publicA// класс Bнаследуетклассу A,класс Bвыведен из A

{

//реализацияB,расширяющаявозможностиА

}


classColorPoint: publicCoord{

//...

}


Режимыдоступа: внешнее,защищенноеи внутреннеенаследование:

Вспомнимописание разделовкласса

сlassимеет разделыс различнымрежимом доступа:

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

private– внутренний,закрытый разделкласса, недоступныйснаружи (недоступени в порожденномклассе тоже).

protected– защищеныйраздел класса,недоступныйснаружи, доступентолько в порожденномклассе принаследованиии.

Важно:

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


Этиже режимы доступа- public,privateи protected- используютсяпри описаниизаголовканаследуемогокласса передименем базовогокласса:

classнаследник>:{public | private | protected} предок>{

//задается одиниз режимов

};


Режимдоступа publicвнешнеенаследование- интерфейсбазового класса(разделpublic)становитсявнешним интерфейсомпроизводногокласса (применяетсячаще всего).

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

Режимдоступа privateвнутреннеенаследование- внешний изащищенныйразделы базовогокласса становитсявнутреннимиразделамипроизводногокласса, недоступныснаружи.

Пример:

classCoord{// базовый класс,описание двумерныхкоординат

protected:

intx,y;

public:

Coord();

SetCoord(intx,int y);

voidDraw();

}


//Через наследованиесоздадим классдля описаниятрехмерныхкоординат
classCoord3D: publicCoord{// внешнее наследование

protected:

intz; // Добавим новоесвойство – ещеодну координату

public:

Coord3D();

SetCoord(intx,int y, int z); // перекрытиеметода,полиморфизм

voidDraw();

}


voidCoord3D::SetCoord(int X, int Y, int Z){ // реализацияметода

z=Z;

//Задать координатыxи yможно черезметод базовогокласса:

Coord::SetCoord(X,Y);// уточнениеимени

//... или прямымприсваиванием:

x=X;

y=Y;

}


//Еще один порожденныйкласс:

classColorPoint3D : protected Coord3D{ // защищенноенаследование

private:

intColor;

intRadius;

public:

Draw();

};


Множественноенаследование

ВС++ при наследованииесть возможностьзадать несколькоклассов в качествебазовых:


classBrush{// кисть длярисования,"пятно"

protected:

intColor;

intRadius;

};


//Новый классявляется наследникомсразу двухбазовых классов:

classColorPoint : protected Coord, private Brush{ //

public:

Draw();//метод Drawиспользуетсвойства иметоды двухклассов

};


classColorPointнаследует двумклассам: Coordи Brush– это и естьмножественноенаследование.


Множественноенаследование– мощное средствоязыка С++, нопорождает рядпроблем.
Невсе системыООП поддерживаютмножественноенаследование(например, Java,С# - не поддерживают).


---------------------------------------------------

Наследованиеклассов (продолжение)

Помним,что наследованиеприменяетсядля построенияиерархииклассов.
Иерархияклассов можетбыть основойсистемы (такVisual ComponentLibrary (VCL)является основойсистем разработкипрограмм Delphiи Builder)

Принеобходимостив производномклассе можноперекрыть(переопределить)свойства иметоды базовогокласса.

Виртуальныеметоды (виртуальныефункции)

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

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

Реализациивиртуальныхметодов в базовомклассе можетбыть переопределенав производныхклассах.

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

Пример:

Иерархияклассов дляграфическогоредактора:

Базовыйкласс Shape(форма, шаблон), порожденныеCircle, Ellipse,Square, Triangle

Увсех порожденныхклассов будетметод Draw.

КлассShape объявляетметод Drawкак virtual.


classShape : public Coord{ // форма,шаблон,фигура

public:


//виртуальныйметод,реализацияфиктивна

virtualvoid Draw(){cout


//или

virtualvoidDraw()=0;// чистый виртуальныйметод (см. ниже),

//реализацияотсутствует,требуется

//переопределениев производномклассе.


}


//Через наследованиесоздаем новыйкласс:

classCircle: publicShape{// окружность,через наследование

protected:

intRadius;

public:

...

voidDraw();// переопределениевиртуальногометода дляCircle

}

CircleC1; // Объекттипа Circle

C1.Draw(); // Вызов методаDraw для объектаCircle

C1.Shape::Draw();// Вызов методаDraw для объектаShape


Shape*pSh; // Указательна базовыйкласс

pSh=&C1; // Указательна базовыйкласс используетсядля

//объекта порожденногокласса

pSh->Draw();// Вызов методаDraw для объектаShape

((Circle*)pSh)->Draw();// Преобразованиеуказателя набазовый класс

//в указательна производныйи вызов

//метода Drawдля объектаCircle

//подробнее см.в литературе


Чистыевиртуальныеметоды и абстрактныеклассы


Чистыевиртуальныеметоды объявляютсяв базовом классекак virtual,но не имеютреализациив базовом классе.
аПроизводныйкласс обязательнодолжен переопределитьэтот виртуальныйметод


virtualvoidDraw()=0;// чистый виртуальныйметод (purevirtual),

//реализацияотсутствует,требуется

//переопределениев производномклассе.


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

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

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


Виртуальныеметоды - этоодно из проявленийполиморфизмаООП.


С++.Основы ООП.


Спецификаторinline


classdate{

intmonth, day, year;

public:

//inline members function

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

voidset_date(char*);

}

...

//inline members function

inlinevoid date::set_date(char* StrDate){

//здесь реализация

}


Приразработкеклассов используетсябольшое числомаленькихфункций.

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

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

Inlineсчитаются всефункции, определенныевнутри описаниякласса.

Функцииможно описатькак inline и внеописания класса.


Статическиечлены класса


Класс- это тип, покоторому строятсяобъекты.

Каждыйобъект имеетсвое содержание,свою копиюданных.

Иногдаесть необходимостьв единых данныхдля всех объектоводного класса.

Такиечлены классаназываютстатическими, они создаютсяс помощью описателяstatic.

Статическийэлемент класса- только одиндля всех объектовэтого класса.


classAirMove{

staticfloatg=9.8; // статическаяпеременная,

... // единая длявсех объектовтипа AirMove

}


Указательthis


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


classTStudent{

char*Name;

intAge;

public:

SetData(char*Name, int Age);

//...

};


voidTStudent::SetData(char* Name, int Age){

strcpy(this->Name,Name);

this->Age=Age;

}


Спецификатордоступа friend– используетсядля объявленияфункций, дружественныхклассу.

Дружественныефункции неявляются членамикласса, но имеютдоступ в закрытыйи защищенныйразделы класса(private и protected).
Дружественныефункции самостоятельны,не вызываютсячерез объектыкласса.
Функцииобъявляютсядружественнымивнутри класса,т.е. класс самопределяет,с кем он "дружит".

Почемубы не использоватьнаследование?

Главнаяцель создания"друзей" – этоперегрузкабинарных операторов(=, +,-…) и операцийввода > - об этом позже.

Дружественнымимогут быть нетолько функции,но и классы.

(см.также Павловская,стр. 187)

--------------------------------------------


С++.Основы ООП.


Переопределениеоператоров(перегрузкаопераций)


ВС++ понятие оператора(операции) трактуетсяочень широко:

операторыарифметические,логические,ввода/вывода,присваивания,индексирования[],
() – скобки –тоже вид оператора,new, delete…


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

Например,присваиваниеили сравнениедля объектатипа TStudentхотелось бызаписать так:


TStudentP1,P2;// Объявлениедвух переменных

P2=P1; // Присваивание

//...

if(P2==P1){// Сравнение

//здесь действие...;

}


ВС++ есть механизмпереопределенияопераций.

Перегрузкаопераций является,фактически,одним из видовперегрузкифункций.

Дляперегрузкиоперации задаетсяфункция операции:


::operator#()
{ // где # - знакоперации

//здесь реализацияоперации

}


Приведемпример переопределенияопераций = и + длякласс Сoord


ClassCoord{ // Координатына плоскости

private:

intx,y;

public:

//...

Coordoperator= (Coordob2); // Переопредениеoperator=, прототип

Coordoperator+ (Coordob2); // Переопредениеoperator+, прототип


}


Переопределимoperator=для Coordкак член класса,вот реализация:


CoordCoord::operator=(Coord ob2){

x=ob2.x;

y=ob2.y;

returnthis;// возвращениеобъекта, которомуприсвоенозначение

}


CoordP1,P2,P3;

//Следующиезаписиэквивалентны:
P1.operator=(P2);// Это вызовoperator=()как метод класса

P1=P2;// Это вызовoperator=()через знакпереопределеннойоперации


Переопределимoperator+для Coordкак член класса,вот реализация:


CoordCoord:: operator+ (Coordob2){

Coordtemp;

temp.x=x+ob2.x;

temp.y=y+ob2.y;

returntemp; //

}


//Следующиезаписи эквивалентны:
P3=P1+P2;// Это вызовoperator+()через знакпереопределеннойоперации

P3=P1.operator+(P2);// Это вызовoperator+()как метод класса


Переопределимoperator+для Coordкак дружественнуюфункцию класса


ClassCoord{ // Координатына плоскости

//Объявлениепрототипадружественнойфункции в описаниикласса:

friendCoord operator+(Coordob1, Coord ob2);

private:

//...

}


//Реализациядружественнойфункции

Coordoperator+ (Coordob1, Coord ob2){

Coordtemp;

temp.x=ob1.x+ob2.x;

temp.y=ob1.y+ob2.y;

returntemp;//

}


Переопределениеоператоровввода/вывода


Терминология:
Вывод/вставкав поток/inserting

Ввод/извлечениеиз потока/extracting


Следующиеклассы реализуютпотоки, объявленыв заголовочномфайле :
ostream– поток длявывода

istream– поток дляввода

iostream- поток дляввода/вывода


Вспоминаем:

cin,cout– имена стандартныхпотоков

inti=10;

couti="i

cout

cin>>i;


Перегрузкаоператоровввода > для создаваемогокласса можетзаменить методыввода/выводаи упроститьиспользованиекласса.


Формазаписи:


ostream&operatorимя_классаob){

//реализациявывода;

}


istream&operator>>(istream &stream, имя_классаob){

//реализацияввода;

}


Операторввода/выводадолжен возвращатьссылку на потокдля корректнойработы такойконструкции:
coutob1ob2ob3obN;

выполняетсявывод ob1-возврашаетсяссылка на поток,
затем выполняетсявывод ob2-возврашаетсяссылка на поток,и т.д.
Слева отоператораввода/выводавсегда должнастоять ссылкана поток.
Перегрузкаопераций ввода/выводане может бытьреализованакак метод класса,т.к. метод вызываетсяобъектомкласса(Object.Method()),и методу приэтом передаетсянеявный указательна объект this.
Форма записиоператораввода/выводапредполагаетслева имя потока,а не объектакласса:

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

Пример:


classCoord{

friendistream &operator>>(istream &In, Coord &Ob2);

friendostream& operator

private:
intx,y;

public:

//Constuctors:

Coord(){x=0;y=0;};

//...

};

//-------------------------------------------------------------

//Переопределениеоператоравывода, дружественнаяфункция, реализация:

ostream&operator

Out

Out

returnOut;

}


cout


Итог:

Перегрузкаопераций – этопроявлениеполиморфизмаООП.

Перегружаемаяоперация всегдасвязана с классом:является членомкласса илидружественнаклассу.

Замечание:Невозможноизменить приоритетвыполненияопераций.


Проработатьэту тему подробнопо литературе(например, Березин.С и С++. стр 249)

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

(файлCoord.cpp)

//A. Zhuravlev.

//OOP. Themes: OOP->Inheritance, OOP->Polymorphism

#include


//Base class Coord

classCoord{

//Redefine input/output

//friendistream &operator>>(istream &In, Coord &Ob2);

friendostream& operator

privateЖ:

intx,y;

public:

//Constuctors:

Coord(){x=0; y=0;}

Coord(intX, int Y){ x=X; y=Y;}

//Implementation:

voidSet_Coord(intX, int Y){ x=X; y=Y;}

intGetX(){returnx;}

intGetY(){returny;}

//Redefine operators:

Coordoperator+(Coord Ob2);

Coordoperator=(Coord Ob2);

};

//-------------------------------------------------------------

//Redefine operations:

CoordCoord::operator+(Coord Ob2){

Coordtemp;

temp.x=x+Ob2.x;

temp.y=y+Ob2.y;

returntemp;

}

CoordCoord::operator=(Coord Ob2){

x=Ob2.x;

y=Ob2.y;

return*this;

}

//-------------------------------------------------------------

//Redefine input/output

ostream&operator

Out

Out

returnOut;

}

/*

istream&operator>>(istream &In, Coord Ob2){

//...

}*/

//------------------------------------------------------------

//Testing:

voidmain(){

CoordC1(10,20);

CoordC2;

//Coord*C3=new Coord(-1,-1);

C2=C1;

C1.Set_Coord(9999,7777);

//C2=C1+C3;//???

cout

cout

//cout

//cout

return;

}


ДВГТУ, ООП,Май 2004

Вопросына экзамен поучебной дисциплине
"Объектно-ориентированноепрограммирование"

I.Общие вопросыпрограммирования

  1. Развитиеязыков программирования.Языки программированияCи C++.

  2. Процедурноепрограммирование.Основные идеиструктурногопрограммирования.

  3. Базовыеконструкцииструктурногопрограммирования,их реализацияв Си.

  4. Циклы.Оператор ветвления.Выбор.

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

  6. Функция:передача параметрови возврат значенийпри вызове.Прототип функции.

  7. Передачапараметровв функцию позначению и поссылке.

  8. Массивы.Строки. Динамическоевыделениепамяти подмассив.

  9. Конструированиесложных типовданных. Структурыв С.

  10. Понятиеуказателя.Работа с указателями.
    Управлениепамятью. Динамическоевыделениепамяти. Утечкапамяти. "Сборкамусора".

  11. Преобразованиепрограммы наС/С++ из исходноготекста в исполняемыймодуль.
    Объектныймодуль. Сборкизагрузочногомодуля.

  12. Заголовочныефайлы. ПрепроцессорС/С++.

  13. ПрепроцессорС, директивы#include,#define,#ifdef,#endif

  14. Проектированиепрограммы,схема иерархиимодулей. Структурасложных программ.


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

  1. Основнаяидея ООП. Классыи объекты. Разделыкласса. Интерфейскласса.

  2. Переходк ООП как этапразвития технологииразработкиПП.

  3. Основныепонятия ООП.Класс и объект.

  4. ПринципыООП. Инкапсуляция.Наследование.Полиморфизм.

  5. Конструированиеклассов. Контрольдоступа к элементамкласса, разделыкласса privateи public.Классы и функции– члены класса.

  6. Конструкторыи деструкторы.

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

  8. Указательthis,модификаторinline.

  9. Наследование:конструированиенового классана базе существующегокласса; разделкласса protected;построениеиерархии классов.

  10. Режимыдоступа: внешнее,защищенноеи внутреннеенаследование.

  11. Множественноенаследование.

  12. Виртуальныеметоды.

  13. Чистыевиртуальныеметоды и абстрактныеклассы.

  14. Переопределениеопераций дляклассов. Пример.

  15. "Друзья"класса (friend),переопределениеоперацийввода/вывода.


III.Практикапрограммирования.

  1. Стильпрограммирования:правила составленияимен, комментирование,отступы.

  2. Содержимоезаголовочногофайла в Вашемпроекте.

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

  4. Прототипыфункций, назначение,использованиев проекте.

  5. Разбиениепрограммы намодули, назначениезаголовочныхфайлов.

  6. Конструированиеклассов набазе структурданных и функцийобработки.

  7. Описаниекласса и объявлениеобъекта, вызовметодов объекта.

  8. Примернаследованияклассов. Примермножественногонаследования.

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

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

  11. Использованиеотладчика длялокализацииошибки в программе.


IV.Ввод/вывод вС/С++.

  1. Понятиепотока и файла.Буферизованныйи небуферизованныйввод/вывод.

  2. Имена стандартныхпотоков в С ив С++, их назначение.Объявлениепотоков, связываниеих с файлами,закрытие потоков.

  3. Ввод/выводв С++. Переопределениеоперацийввода/вывода.