Ответы на билеты
.pdf
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(constchar* ...); // заканчивающийся
нулем список
// обозначений
клавиш
// ...
virtualintask(); };
Здесь важную роль играет функция 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/abstractclassvsinterfaceinc
Сериализация процесс вывода полиморфных объектов (например, контейнер). Проблема с вводом – в С++ единств способ создать объект – вызвать его конструктор => гдето д.б. описан процесс перевода какойлибо
структуры данныхв последовательность битов. Обратной к операции сериализации является операция десериализации(структуризации) — восстановление начального состояния структуры данных из битовой последовательности.
Сериализация используется для передачи объектовпо сети и для сохранения их в файлы.
Например, нужно создать распределённое приложение, разные части которого должны
обмениваться данными со сложной структурой. В таком случае для типов данных, которые
предполагается передавать, пишется код, который осуществляет сериализацию и
десериализацию. Объект заполняется нужными данными, затем вызывается код
сериализации, в результате получается, например, 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 . Вместо разности четвертым параметром можно задать ii i1
другую операцию. Функция возвращает итератор на элемент, следующий за концом результирующей последовательности.
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);
Этот алгоритм является обратным предыдущему, то есть вызов для одной и той же последовательности сначала одного, а потом другого алгоритма приведет к исходной последовательности.
