Скачиваний:
152
Добавлен:
08.07.2017
Размер:
4.08 Mб
Скачать

17. Контроль семантической корректности программ

Из ответов

Методика Флойда, затем развита Хорром и Виртом. Первонач ориент на процедур ЯП…

Рассм­ся спецификация программы вида: {P} S {Q}, P, Q ­ логические формулы, описывающие взаимосвязь нач и заключит состояния памяти пр­мы, S ­ программа,. Читается так: если P истинно до начала вып­ния S, то Q ­ истинно после ее завершения.

P ­ предисловие, Q ­ постусловие.

Методика док­ва: Для пр­мы формулируют P и Q. Считая P ­ истинным, пытаются доказать истинность Q , последовательно применяя правила вывода. Если доказано, то программа семантически корректна. ​Правила вывода​для осн алгор конструкций:

x

x

​ ​

1.Для операций присваивания: {Pe } x:=e {P} ; {Pe } – выражение, полученное из Р

 

подстановкой е вместо всех свободных вхождений Х в Р; вхождение свободно, если оно не связ с кванторами всеобщности и сущ­ния.

2. Цикл repeat…until: {P}S{Q},

{P} repeat S until B {QΛB} //рис см внизу

Док­во семантич корректности вручную даже для простых пр­м нетривиально. Прогр­х ср­в полностью решающих задачу нет. Возм только поддержка процесса аналитич док­ва => данная методика прим лишь для новых алг­мов и критич важных фрагментов программы.

ОпрИнварианты объектов​– набор логич условий, одн­но хар­щих правильный объект данного класса. Для корректной работы с объектами инвариант д. сохр­ся. Предусловия и постусловия ​­ условия, которые д.б. выполнены до начала выполнения метода и справедливы после его окончания. Конструктор созд­т объект,в том числе вып­ся инвариант. При работе метода инвариант м. изм­ся, но по окончании восст­ся. Нарушение условий – ИС. Проверки целесообр на этапах отладки и тестир, затем д.б. отключены.

В С++ сущ­т ​механизм подтверждений​­ проверка условий на этапе отладки: void assent (int expr) из <assert.h> ­ проверяет заданное выражение, в случае нарушения выдает станд диагностику (Nфайла,Nстроки) и вызывает abort.

// Факториал отрицательного числа не считается

assert(n >= 0);

Сигналы​­ (signal.h) – Механизм для контроля асинхр событий, аппаратно зависим. Сигналы м.б. аппаратными, в т.ч. генерируемые микропроцессорами, и программными.

Для программной генерации: int raise(int sig). Для установки реакции на возбужденный сигнал исп­ся ф­ция signal(SIGABRT,my_abort)­связывает тип сигнала с его обработчиком void my_abort(int SIG)

18. Типы классов: конкретный, абстрактный, узловой, интерфейсный

ТИПЫ КЛАССОВ

 

Конкретный

­ определяет конкретное понятие из предметной

области системы.

 

Примеры– комплексные числа, символы нац алфавита, односвязный список, контейнеры STL, встроен типы в ЯП (квадрат).

Свойства:

▪Точно соответствует описываемому понятию ▪Обеспечивает эффективную реализацию

▪Минимально зависит от других классов и в этом смысле являются изолированным

▪Не предназначен для использования в качестве базового (нерекомендуется использовать в качестве родителя)

▪Как правило не имеет вирт. функций ▪Может порождать объекты.

Повторное их исп­ние обеспеч за счет агрегирования, а не наслед.

Недостатки наследования при реализации конкретных типов:

▪менее эф­ные методы при наслед (вызов вирт функции медленнее, чем обычной; вирт функции нельзя сделать inline)

▪Исп­ние динамич памяти. Прим вирт функции требует работы через указатели или ссылки и динамич памяти для хранения об­тов, т.к. их размер разный. В рез­те в программе резко сокращ число истинных локал перемнных.

▪Неудобство для прогр­та, т.к. увелич уровень косвенности.

▪При наслед отн­но снижается инкапсуляция.Вирт ф­ции м. замещать, а защищенными полями м. манипулировать из наследуемых классов.

●​Абстрактный ­ абстракция группы родственных понятий (список, множество) // класс, в котором выделены свойства подкласов

Свойства:

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

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

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

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

Узловой­ расширяет интерфейс абстрактного базового ( //интерфейс­­ виртуальные функции). Может порождать объекты и предназначен для исп­ния в кач­ве базового.

Например: Фигура <|­­­­ Четырехугольник <|­­­­ Квадрат, в этом случае Четырехугольк являеся узлом

Свойства:

▪Исп­т свои базовые классы для реализации части своих возможностей ▪Имеют большое число открытых методов ▪Имеет нетривиал конструкторы. 2 вида:

1.​Абстрактный узловой­ не может порождать объекты 2.​Конкретный узловой­ не предназначен для использования в качестве

базового.

пример для понимания​:

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

classdialog_box : publicwindow { // ...

public:

dialog_box(const​​char* ...); // заканчивающийся

нулем список

// обозначений

клавиш

// ...

virtual​​intask(); };

Здесь важную роль играет функция ask() и конструктор, с помощью которого программист указывает используемые клавиши и задает их числовые значения

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

classMyInterface{ public: // Empty virtual destructor for proper cleanup virtual~MyInterface() {} virtualvoidMethod1() = 0; virtualvoidMethod2() = 0; }; //Интерфейс, в нем не определенны виртуальные функции

classMyAbstractClass{ public: virtual~MyAbstractClass(); virtualvoid Method1(); virtualvoidMethod2(); voidMethod3(); virtualvoidMethod4() = 0; // make MyAbstractClass not instantiable}; //Абстрактный класс, в нем

определенны виртуальные функции

Множественные интерфейсы​– многократн исп­ние абстрактных типов в комб с конкретными для получения разл интерфейсов.

Насыщенные интерфейсы​­ объединение в базовом классе полезных функций потомков; возникают когда конкретные типы делаются производными от абстрактных. Плохое решение, если не все потомки поддерживают интерфейс. Характерны для языков с единичным наследованием..

Фабрики классов​­ класс с виртуальной функцией для создания объектов другого класса. Такая функция наз. "Виртуальный конструктор".

class X

{

public :

virtual X* clone() {return new X(*this)}; virtual X *newX() {return new X();}

}

http://stackoverflow.com/questions/12854778/abstract­class­vs­interface­in­c

Сериализация ­ процесс вывода полиморфных объектов (например, контейнер). Проблема с вводом – в С++ единств способ создать объект – вызвать его конструктор => где­то д.б. описан ​процесс перевода какой­либо

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

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

Например, нужно создать распределённое ​приложение, разные части которого должны

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

предполагается передавать, пишется код, который осуществляет сериализацию и

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

сериализации, в результате получается, например, ​XML­документ.

Многие объекты, в т.ч. и контейнеры, м. разделить на 2 части: дескриптор и представление.

Дескриптор​­ управляющая часть, которая контролирует доступ, распределяет память, управляет блокировкой и тд.

Представление​­ информационная часть, которая хранит состояние объекта. Для работы с такими объектами достаточно передавать дескр­р и работать с об­тами через него (т.е. это расширение понятия указателя). Если дескриптор поддерж­т все или почти все метода представления, то он наз­ся “заместитель” (или прокси).

При работе через дескрипторы возникает проблема определения момента представления в том случае если дескрипторов в программе несколько. Для ее решения исп­т обобщенный дескриптор. Следует считать случаи копирования дескриптора и удалять представления только когда будет удален последний дескриптор.

19. Библиотеки контейнерных классов

1.Объектная библ­ка контейнеров (OBCL) Св­ва:

▪Все объекты, к­рые помещ в контейнеры, д.б. произв от общего абстракт класса object. Такие контейнеры – интрузивные (навязчивые)

▪В классе польз­ля д.б. переопр­ны чистые виртуал ф­ции: isA, nameof, isequal,printion. ▪От object производ­мы явл и сами контейнеры. В рез­те в контейнере м храниться др контейнеры. Контейнеры имеют 1 внешний итератор, к­рый прим ко всем объектам в контейнере рекурсивно + один внутр аппликатор foreach.

▪Класс object имеет вложенный класс TShouldDelete для управления статусом владения. По умолч все контейнеры обладают своими объектами, поэтому в них нельзя размещать локал статич объекты. С пом спец метода их можно лишить статуса владения.

2.Биб­ка шаблонов контейнеров (BIDC) вкл­т шаблоны контейнеров и итераторов, исп­т наследование, контейнеры неинтрузивные. Св­ва:

1)все контейнеры делятся на 2 группы:

▪низкого уровня (векторы, списки, дерево двоич поиска); ▪верхнего (массив, мн­во, очередь, стек, словарь); 2)Контейнеры м.б.:

▪прямыми (они никогда не владеют своими объектами, хранят копии, не м.б. полиморфными);

▪косвенные (по умолч владеют объектами, классы насл­ся от TShouldDelete); 3)по способу упр­ния порядком хранения объектов:

▪простые (не переразмещают объекты);

▪счетные (операция add добавл объект в 1ое свободное место, а после удаления контейнеры переупак­ся);

▪упорядоченные (после каждого add/delete сортируются); 4)по способу упр­ния памятью:

▪с управлением (м. исп­ть аллокатор поль­ля ); ▪без упр­ния – исп­ся стандарт аллокатор.

Аллокатор­­ это объект, который управляет расположением элементов контейнера в памяти.

3.Стандартная библ шаблонов (STL) содержит шаблоны контейнеров и итераторов, но ее нельзя отнести к ОО библиотекам. Контейнеры не имеют виртуал ф­ций и не предназнач для дальнейшего наследования. Сделано в целях эффективной реализации, но слабо годится для расширения.

2 способа расширения:

1)агрегирование станд контейнеров;

2)оборачивание контейнера с пом дескриптора с ОО св­вами и постр на этой основе своей иерархии классов.

3 категории контейнеров:

контейнеры последовательностей (vector, list, deque),

ассоциативные (set,multiset,map.multimap) //обращение к объектам по ключу (1­­Баканов)

и адаптеры контейнеров (stack, queue, priority_queue).

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

http://samoychiteli.ru/document26299.html

Численный метод. В эту библ­ку входит один контейнер – численный массив. С ним м. работать через срез. Фактически срез выделяет каждый Эл­т в массиве. 2ой способ работы – через маску. Маска наклад на массив значение 0 и 1: 1­эл­т массива попадает в рассм­ние, 0­нет. (// по маске выбираем элемнты массива: 1­­ выбираю, 0­­ не выбираю). Косвенный массив – хранит индексы эл­тов массива, с к­рым будет вып­ся работа.

Обобщенные численные алг­мы служат для накопления рез­тов под посл­тями эл­тов в массиве.

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

20. Численные методы еще можно почитать в 22 главе страуструпа

Обобщенные численные алгоритмы

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

<numeric>.

Обобщенные численные алгоритмы

Алгоритм

Выполняемая функция

 

 

accumulate

Накопление

 

 

inner_product

Скалярное произведение

 

 

partial_sum

Расчет суммы с накоплением

 

 

adjacent_difference

Вычисление разности между смежными элементами

 

 

accumulate

Первая форма алгоритма accumulateиспользуется для накопления суммы элементов последовательности, заданной итераторами firstи last.Начальное значение суммы (обычно это 0) задается третьим параметром. Тип этого параметра определяет тип результата (функция возвращает вычисленную сумму):

template <class In, class T>

T accumulate(In first, In last, T init)

Вторая форма алгоритма accumulateпозволяет выполнять над третьим параметром и очередным элементом последовательности заданную операцию:

template <class In, class T, class BinOp>

T accumulate(In first, In last, T init, BinOp binary_op)

В приведенном далее примере вычисляется сумма, произведение и сумма квадратов элементов массива:

#include <iostream> #include <numeric> #include <functional> using namespace std;

int sumkv( int s, int x){ return s+x*x;} int main(){

const int m=5;

int a[m]={3,2,5,1,6}, sum=0,mul=1,sum2=0; cout<< accumulate(a,a+m,sum)<<endl;

cout<< accumulate(a,a+m,mul,multiplies<int>())<<endl; cout<< accumulate(a,a+m,sum2,sumkv)<<endl;

return 0;

}

inner_product

Первая форма алгоритма inner_productиспользуется для вычисления скалярного произведения двух последовательностей (скалярным произведением

последовательностей аи bявляется выражение ∑ai*bi). Начальное значение произведения задается четвертым параметром. Тип этого параметра определяет тип результата (функция возвращает вычисленное произведение):

template t<class Inl. class Iп2. class Т>

Т inner_product(Inl firstl, Inl lastl, In2 first2, T init);

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

template t<class In1, class In2, class T, class BinOp1, class BinOp2> T inner_product(In1 first1, In1 last1, In2 first2, T init, BinOp1

binary_op1, BinOp2 binary_op2);

Следующий вызов вычисляет произведение сумм соответствующих элементов последовательностей аи b:

cout<<inner__product(a, а + m, b, mul, multiplies<int>(), plus<int>());

partial_sum

Алгоритм partial_sumформирует последовательности из частичных сумм элементов. Например, для последовательности чисел 3 1 2 3 5 результатом будет 3 4 6 9 14, то есть каждый элемент результата равен предыдущему элементу, увеличенному на текущий элемент исходной последовательности.

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

template t<class In, class Out>

Out partial_sum(In first, In last, Out result); template t<class In. class Out. class BinOp>

Out partial_sum(In first, In last, Out result, BinOp binary_op);

adjacent_difference

Алгоритм adjacent_difference выполняет вычисление разности между смежными

элементами, то есть d=a–a. Вместо разности четвертым параметром можно задать iii­1

другую операцию. Функция возвращает итератор на элемент, следующий за концом результирующей последовательности.

template t<class In, class Out>

Out partial_sum(In first, In last, Out result); template t<class In. class Out. class BinOp>

Out partial_sum(In first, In last, Out result, BinOp binary_op);

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