Ответы на билеты
.pdfДиаграммы взаимодействия (interaction diagrams) описывают взаимо действие групп объектов в различных условиях их поведения. UML определяет диаграммы взаимодействия нескольких типов, из которых наиболее употребительными являются диаграммы последовательности. Обычно диаграмма последовательности описывает один сценарий. На диаграмме показаны экземпляры объектов и сообщения, которыми обмениваются объекты в рамках одного прецедента (use case).
12. Архитектура и стиль программной реализации
Из ответов
Архитектура это внутренняя структура программы. Стиль программной реализации – способ представления арх решений в программном коде. Связь – при плохом одном,
плохое и другое. 2 понятия стиля:
1)Примитивное. Цель – объяснить конкретный участок кода. Что входит: именование idров, комментарии, правила испния goto, рефакторинги.
2)Современное. Цель – выразить арх решение. Включает: иерархия классов, реализации отношений, упрние видимостью, пространство имен и доступ, обработка исключит ситуаций, контроль аномал поведения прмы, проверка пред и постусловий, контроль инвариантов объектов, испние шаблонов проектирования, испние и фиксация выпных рефакторингов.
На архру и стиль влияет испмый ЯП и библиотеки классов.
Идентификаторы и управление видимостью.
Объект на физическом уровне – идентифмая область памяти, которая м содержать значение объекта. Значение имеет связанное с ним имя и тип. Имя – либо идентификатор, либо выражение указывающее на объект.=> м сущть безымянные объекты. Объявление делает известным идентификатор в данном контексте.
Определение устанавливает связь идентификатора с типом и инициализирует объект, т.е. распределяет память, и возможно инициализирует значением. => Опр только одно (class P{..};), а объявлением м.б. много (class P;).
Явное управление видимостью, пространства имен.
Область действия id– часть программы, где идентификатор может использоваться для доступа к объекту. Виды областей действия в С++:
1)Локальная или типа блок {__... };
2)оператор (до конца оператора – for(in i=…)),
3)прототип функции (до конца прототипа, ‘;’),
4)глобальная или файл (до конца файла),
5) класс
Пространство имен – область действия, где id д.б. уникален. В С++ действует общее прво имен для типов и нетипов. Поэтому действует след правило: не м.б. в одной облти действия одно имя испно для 2х типов сразу. 2ое правило – если одно имя для одной облти действия исп для типа и нетипа, то имя нетипа скрывает имя типа. (имя типа – класса, нетипа – переменная, фция) Для доступа к имени типа следует испть слово class: class Point a(1,1);
Область видимости – часть области действия, где id м.б. испн для нормального доступа к объектам. Обычно обл Д и В совпадают. Глобальный id м.б. скрыт локальным:
int a = 5; void f()
{
int a = 3;
int b = a; //a=3 использует локальную переменную
}
void h()
{
int c = a; //c=5 используется глобальная переменная
}
Продолжительность жизни объекта – время пока idру соответствует в памяти реал объект. Виды памяти:
1)статическая – память распред в начале выпния прмы и сохр до конца выполнения. Объекты: об с областью видимости типа файл (глобальная); с локал обл действия, но со специф облти памяти static, extern (в другом файле находится этот объект); статич члены класса. Созд с пом конструктора, разруш с пом деструктора – вызыв. при завершении прмы автоматически. А если конструктор сделать как private или protected, то это явно запрещает создание таких объектов в прме. Статич члены класса инициализ не в теле, а в глобал облти действия., т.к. конструктор д.б. вызван лишь 1 раз
class Point
{
static int num = 0;
}
Point a, b; b.num = 5; a.num = 3;
std::cout << b.num; //b.num=3, так как num static
2)локальная. Локал объекты. Хранятся в стеке. Созд конструктором, разруш деструктором при выходе из облти дейтсвия. Если конструктор private/protected, то создать нельзя.
3) Динамическая. Временем созд и удалением упрт программист с пом new и delete. Такие объекты располагаются в куче.
Point* a = new Point();
...
delete a;
Спецификаторы класса памяти
▪auto (действует по умолч для локал объектов), Point a;
auto b = a; //автоматически присваивает b тип, как у a, т.е. тип Point ▪extern (статич продолж жизни, внешний тип связывания),
▪ static (статич продолж жизни, внутр тип связыв), ▪register(рекомендация компилятору размещать объект в регистре)
Модификаторы– харт изменчивость объекта: ▪const (предотвт изменение объекта в памяти):
▪ volatile – асинхронно изммый или подвижный. Запрещает компилятору оптимизировать эту переменную. Указание компилятору на то, что знач объектов м.б. измся асинхронно извне прмы.
int a=3; a=5;
int c = a;
Компилятор будет выполнять следующую последовательность: int a =5;
int c =a;
Но, если установить volatile, то выполнится все, что написано в программе volatile int a = 3;
▪ mutable – “мультируемый”. Член объекта м измся даже если сам объект costный
Управление облтью видимости В С++ idры м.б. явно сгруппированы в именованном прве имен с пом конструкции namespace имя {}. Цель испния – логич группировка имен в отлич от физич, края реался распределением idров по файлам и последующем вклм файла с испнием директивы include. С пом прва имен м имитировать понятия пакета, интерфейса, и явно задавать завти м/у классами.
Осн возможности:
▪Вне прва имен имя, объявленное в нем, м.б. опрно и испно с пом конструкции NS :: i к статич членам класса.
▪Допускается прострное X::Y::i (Y вложен в Х) namespace n1
{
namespace n2
{
static int a = 2;
}
}
…
int b = n1::n2::a; //b=2
▪М ввести в любую область видти имя, описанное ранее: using x::i; после этого с i м работать без указания прва имен. Аналогично м ввести все имена из прва имен: using namespace X.
▪Конструкция using испся также при наследовании для оргции правильного набора наследных фций в данном узле графа наследования.
▪В каждой единице трансляции сущт неименное прво имен, доступ к кот осущ с пом
:: ▪Для прва имен м вводить псевдонимы: namespaceTemplateLibrary namespace STL :: STL = StandartTemplateLibrary;
▪М объединять прва имен: namespace Z {using namespace X; using namespaceY;}
▪М строить новые прво имен на основе отбора имен из других namespace Z{using X::f{};}
▪В имеющееся прво имен м добавлять новые имена namespace X {int g{};}
▪С испм прва имен дополняются правила, действующие при перегрузке фции. В случае вызова фции без указания прва имен, она ищется сперва в текущей облти видти, затем в првах имен аргтов, включая их классы и базовые классы, затем дейтст станд правила.
void h(int a); void h(int a, int b);
Прва имен и проектирование интерфейса Цель использования прва имен – локализовать код, т.ч. не было конфликта испния имен.
13.Стиль реализации класса
●Члены класса
Поле подобъект объекта (или класса в случае статического поля).
class Point
{
private:
int x; //поле int y; //поле
Point* next_point; //указатель
public:
Point() //конструктор по умолчанию
{ x = y = 0;} //т.е. х и у будут по умолчанию равф нулю void setXY(int x, int y); //метод
}
В зависимости от вида ассоциаций между классами поле может быть указателем, ссылкой или самим подобъектом.
1)Указатель: возникает вопрос о статусе владения объектом подобъекта. В библиотеках классов существуют средства для управления статусом владения. Например:
●Косвенный контейнер может владеть хранимыми элементами, тогда при его уничтожении они должны уничтожаться.
●Контейнер и внешний итератор: связь может быть разная. Например, ссылка на контейнер: итератор нельзя перенастроить в теч. жизни на другой контейнер.(Итератор объект, который предоставляет доступ к элементам контейнера)
Метод: при проектирование набора методов определяется полный набор возможных методов для данного класса.
I.С точки зрения необходимости реализации рассматриваются следующие виды методов:
1)конструктор по умолчанию,
2)конструктор копирования,
3)конструктор с параметрами + конструктор преобразования типа из произвольного класса в данный A(const& B b) {getAFromB(b);}
4)деструктор
5)модификаторы (set)
6)селекторы (get)
7)операторы:
a)присваивания (=)
b)сравнения (==, !=)
c)больше, меньше (>, <)
8)операции преобразования типа (от данного класса в произвольный) (конструктор с нужным параметром, оператор преобразования типа) operator B() {}
9)итераторы для контейнеров (аппликаторы функции)
II. Формируется интерфейс класса с совместным использованием (перегрузки) механизма присвоения начальных значений. Добавляются операции удобные пользователю и связанные с обработкой Exception.
Локальные и вложенные классы традиционно так реализуются классы исключений, классы для проверки пред, пост условий и инвариантов.
Инвариант представляет собой утверждение относительно класса. Например, класс Account (Счет) может иметь инвариант, который утверждает, что balance == sum(entries.amount()). Инвариант дол жен быть «всегда» истинным для всех экземпляров класса. В дан ном случае «всегда» означает «всякий раз, когда объект доступен для выполнения над ним операции».
●Ссылки
type &rt = t; // rt ссылка, t инициализатор (обязателен кроме случаев внутри
класса или extern ссылок) void f(int& par1)
{
par1 = 2;
}
int a=3; f(a);
//а=2 так как объект передается по ссылке Ссылка константный указатель на инициализатор или результат его
преобразования к типу type, при каждом использовании которого автоматически выполняется операция разыменования.
t инициализатор должен быть lvalue (переменной) (то, что слево от знака операции) и типа type иначе rt должна быть ссылкой на константу.
Семантика передачи параметров в методы определена как инициализация. void f (const int &rci){...} //при f(1.5) > const int &rci = 1.5;
Аналогично при возврате значения.
Если не const, то пусть f(x) (x double), тогда int &rci = x не может быть, т.к. double != int.
Если не const, то не беспокоимся ни о чем кроме несовместимости. Если нет const, то подразумевается изменение параметра внутри функции.
Ссылки применяются:
1.В качестве параметров методов для имитации способа передачи значений параметров по ссылке. Семантика передачи параметров и возврате значения в функцию определена как инициализация. Таким образом, отсутствие const в параметре ссылки явно запрещает использование преобразования типа “указывает на то, что передаваемый в функцию объект будет модифицирован ей”
2.Передача в методы больших структур данных (адрес структуры в памяти(без копирования)). Можно было бы использовать указатели, но это хуже, т.к. лишний уровень косвенности.
3.Использование ссылок в качестве возвращаемых значений функции.
Слева от оператора присваивания применяет конвеерную обработку:
f(obj) =f(f(f(obj))); obj.setBla().setBoom().
123
const Object& setBla() {...; return *this;} const Object& setBoom() {... return *this;}
Связь двух классов реализуется с помощью ссылки. Явно указывает на невозможность связи двух других экземпляров. Правильней всего в итераторе сделать поле ссылки на контейнер и инициализировать это поле в конструкторе итератора.
4. Использование ссылок для реализации функциональных объектов (функторов). void (*funcname) (int i, int j); void bla (int a, int b) funcname = bla;
Function
Манипулятор без параметров(функция как объект): typedef ostream & (*Omanip)(ostream &);
ostream & operator << (ostream &os, Omanip f) {return f(os);}
ostream & flush (ostream &); //сброс буфера в поток count << x << flush << y << flush;
Манипулятор с параметром: template <class T> class OManip
{
T i;
ostream & (*f)(ostream &,T); public:
OManip(osrteam &(*ff)(ostream &, T), T ii) : f(ff), i(ii) {};
friend ostream &operator << (ostream &os, Omanip &m) {return m.f(os, m.i); };
};
osrteam &precision (ostream &os, int i)
{
os.precision(i); return os; };
Omanip<int> setprecision(int i)
{
return Omanip<int>(&precision, i);
};
cout << setprecision(4) << x };
Пример:
#include <iostream.h> #include <iomanip.h> int main()
{
cout << setiosflags(ios::fixed);
cout << setprecision (2) << 1000.243 << endl; //endl перевод каретки на новую строку манипулятор без параметров
cout << setw (20) << "Hello there."; //setw устанавливает ширину поля равной 20 манипулятор с параметром
return 0;
}
Локальные и вложенные классы.
Локальные (local) класс, описанный внутри функции. void hello()
{
class SayHello
{
public:
void print()
{
std::cout << “Hello from SayHello”;
}
}
SayHello a; a.print();
}
int main()
{
hello();
}
Свойства:
1.Не должно быть статических членов.
2.Нет специального доступа.
3.Нельзя использовать автоматические переменные в классе.
4.Методы должны иметь только внутреннее описание. Применение:
1.Для сокращения глобального пространства имен.
2.Указания тесной семантической связи между функцией и классом (или классом
иклассом) похоже на композицию.
Вложенный класс (nested) описание внутри другого класса. class X {...class Y{};};
X::Y b; //использование Свойства:
1.В классе X нет подобъекта Y.
2.Нет специального доступа между членами X и Y.
3.Описание методов Y м.б. как внутренним, так и внешним.
Страуструп утверждает, что существует возможность выбора сделать класс другом или вложенным классом, на самом деле дружба это доступ, а вложенность это видимость.
Доступ
Два способа использования: доступ к членам, доступ при наследовании.