
Ответы на билеты
.pdfСпецификаторы: private, protected, public.
Доступ к членам: первоначально считается все поля private, методы public. Если некоторые поля нужно наследовать делаем их protected. Остальные отступления д.б. обоснованы.
Особенности использования private и protected:
●Явный запрет выполнения соответствующих операций. Можно запретить: конструкторы, деструктор, операции преобразования типа.
●Если private или protected испозьзуется при наследовании, то базовый класс является детально реализуемым. В этом случае запрещается неявное преобразование типа из производного в базовый.
●Реализация контроля доступа выполняется статически. Проверка выполняется компилятором, когда еще механизм виртуальных функций не действует.
class B
{
public:
virtual void f();
};
class D : public B
{
private: void f();
};
void g()
{
D d;
B *pb = &d; D *pd = &d;
pb > f(); // хорошо
pd > f(); //будет ругаться
};
(В конспекте следом еще идет коррекция доступа, но так как явного такого вопроса здесь нет, то я его не включила)
Функции члены и функции друзья.
Друзья функции или классы, которым разрешен доступ к закрытым членам класса. Отношение дружбы не транзитивно и не наследуется.
Совместное использование функции и операции(перегрузка):
Реализуется за счет “искажения” имен. Функции получают новые имена, включающие информацию о типах и числе параметров. Не должны отличаться только типом возвращаемого значения. (int f(int) и int f(int, int разные функции))
Правила перегрузки операций:
●нельзя вводить новые знаки операций;
●нельзя менять существующие;
●нельзя изменять старшинство, ассоциативность, число параметров операций;
●нельзя перегружать операции “::”, “.” и др.
●можно менять число параметров у “()” вызова функции.
Операция может рассматриваться как глобальная или как операция член класса.
operator @(x) или x.operator @()
Совместное использование и область видимости:
Функции в разных областях действия не являются перегруженными в отличие от функций из разных пространств имен или функций, полученных при пересечении областей видимости классов(множ.наследование). В последнем случае рекомендуется явно формировать набор совместно используемых функций с помощью using. А для разрешения неоднозначностей при выборе функций вводить inline функции. namespace a
{
void f(int a); //a::f(5)
}
namespace b
{
void f(int a, int b); //b::f(5,10)
}
inline void f1(int n) {f1(long(n));};
Отличия функций друзей от функций членов:
Некоторые функции разумно реализовывать как члены класса, а некоторые как друзья
class complex {
complex operator += (complex);
friend complex operator+ (complex, complex); };
Члены класса всегда имеют дополнительный неявный операнд this, для которого не применяются преобразования типа. Для friend же все операнды равнозначны.
Значения параметров по умолчанию Применяется вместо совместного использования
для получения коротких форм вызова функций. Значения параметров последовательно задаются справа налево в списке. Изменить значение по умолчанию нельзя. Реался эфно за счет автомати добавления соотвго набора совместно испмях inline фций Имеем f( , , = 3).тогда будет inline f( , ) {f ( , , 3)}
int sum(int a, int b = 3) //b=3 параметр по умолчанию
{
return a+b;
}
int s1 = sum(5); //s1=8 int s2 = sum(5, 1); //s2=6
Неопределенное число параметров. printf (const char* …) 1ый параметр – формал строка,
которая позволяет понять колво и тип параметров при вызове. Для работы с переменным числом парров испся набор макросов из “stdorg.h”. Внутри таких функций объекты, переданные в них не считаются объектами, работа с ними осущся как с фрагментами памяти. Это позволяет обойти контроль за созданием и уничтожением объектов классов, реализованный на уровне конструкторов и деструкторов.
Функционал объекты Прим когда требуется нечто вроде фции, но с сохраненным
внутренним состоянием. Иногда такими обтами показывают те, у кот определен оператор

classcompare_class{
public :
bool operator()( int A, int B) {
return (A <B);
}
};
// объявление функции сортировки template<class ComparisonFunctor> voidsort_ints(int *begin_items, int num_items, ComparisonFunctor c);
intmain() {
int items[] ={4,3,1,2}; compare_class functor;
sort_ints(items, sizeof (items) /sizeof (int ),functor);
}
Статические члены – члены со спецификатором static.
Создается 1 экземпляр от члена, разделяемый всеми объектами данного класса. Это отдельный объект, а не подобъект! Если сущт const объект класса, к которого сущт статич член, то он не становится автоматич константным.
Обращаться можно как через класс, так и через объект: B :: st; ab.st; pb > st. Сущт еще как до момента появления 1ый объект, так и после уничтожения последнего объекта. СЧ должны быть определены в глобальной области действия. Имеют статический класс памяти и внешний тип связывания, т.к. доступны во всех
файлах, где есть описание соответствующего класса. У статических методов нет this (нельзя использовать).
Особые методы класса
1.Конструктор по умолчанию. Х::Х() создается автоматически, если в классе нет других конструкторов.
2.Конструктор копирования. Х::Х([const] X&) автоматически создается только если в классе нет конструктора копирования.
3.Констрр преобразования типа X::X{Y}
4.Операция присваивания. X::operator = (const X&) если нет const, то нельзя. Создается автоматически, если не описана в классе отдельно.
5.Деструктор
▪X b; конструктор по умолчанию; ▪X a(b); копирования;
▪X a(1);преобрния типа;
▪ X a = b; копирования (а еще не сущт);
▪ a = b; оператор присваивания (к уже сущщим объектам)
Для решения проблем с неправильным преобразованиями типов при вызове конструктора можно при объявлении кра испть спецификатор explicit, крый указт на то, что данный конструктор должен вызываться явно
string s = 'a'; |
explicit string (int); |
Если конструктор описан с explicit, то может использоваться только явно.

14. Иерархии классов Иерархия ранжированная и упорядоченная система абстракций. 2 вида: 1)классов за
счет наследование; 2) объектов за счет агрегирования. Наследование: 1)одиночное B <| D Структура объекта D:
B
часть D
}подобъект класса В 2)множественное граф.
Проблемы: дублирование полей и методов. (Внутри DD 2 подобъекта B. ) => Вирт наследование Но пробл с дублир вызовов методов не устраняется
Виртуальное наследование позволяет организовать связь между классамибратьями
VB {virtual void f{}} |
|
D1 {virtual void f{}} |
D2 {virtual g() {f()}} |
При вызове g() из DD в подобъекте D2 внутри g() |
будет испся фция f() класса D1. Такие классы назся подклеенными.
Др рис: везде {f()}. При вызове f для DD метод f вызовется 2 раза. Та же проблема с конструкторами. Она решается след образом: введено понятие полный объект– такой, который не является подобъектом базового класса другого объекта; его класс называют конечным производным. DD dd – полный, внутри него есть подобъекты, они неполные. хотя D1 d1 – полный
Правила: подобъект вирт базового класса полного объекта при множ наследовании инициализируется особым образом: 1) своим конструктором по умолчанию и остальные не выполняются; 2) либо констрром конечного произв класса в списке инициализации (при этом разрешается инициализировать не прямую базу). Все остальные инициализации игнорируются.
Таблицы вирт функций: 1. Одиночное. Пример: class B
{
public:
int b;
virtual void f(int);
virtual void g(int){return b+5}; virtual void h(int);
};
class D : public B
{
public: int d;

void g(int){return b2};
};
class DD : public D { public:
int dd; void h(int);
};
Если в классе сущт хотя бы одна вирт фция, в каждый объект добавл указ на табл Вирт фций и создается 1 табл вирт фций, содерж данные, необхмые для вирт вызовов.
DD* pdd=new DD; pdd>g(2); => (*(pdd>vptr[1]))(pdd,2)
2.Множ наслед. Пр: :
class B1 {public: virtual void f()}; class B2 {public: virtual void f();virtual void g()}; class D:public B1, public B2 {public: void f();};
константа времени компиляции
При испнии вирт фций: увеличивается размер объектов на размер указателей; для каждого класса строится в памяти таблицы Вирт фций. В многофайл проектах м.б. проблема размещения таблиц в файлах, учитывая принцип раздел компиляции. Для упрния этим процессом в среде прния обычно испся след опции: 1)smart virtual tables (единая) и local (создаются копии); 2)при раздел компиляции: public(в данном файле ТВФ, доступные извне) и external (ссылки на внешние таблицы)
Динамическое определение типа объекта.
Способы:
1.добавить в объект поле “тип”. “”в месте, где нужно будет опрть тип будет конструкция switch. при добавлении нового типа эту конструкцию надо будет переписывать, что при раздельной компиляции м.б. невозможно.
2.механизм вирт фций. class пределяем тип по адресу статического поля в объекте
B {public: static int r; virtual int *mytype();}; int* B :: mytype() {return &r;} возвращает адрес r class D : public B {public: static int r; virtual int *mytype();}; int* D :: mytype() {return &r;} void f(D *pb) {if (pb>mytype()==&D::r) {…}} // признак типа – адрес статич поля
Если в классах есть вирт фции, то размер объекта не увелич, иначе увелич на размер rptr, что для мелких объектов м.б. неприемлемо.
3.Исп технологии RTTI. typeid – возвращает ссылку на объект типа type_info и м возбуждать искл ситуацию badtypeid. Класс type_info имеет: Вирт деструктор, операцию сравнения, оп упорядочения before, преобразование в тип char* для получ текстового представления имени типа. Запрещены: конструктор копирования и оп присваивания (они приватные). Данный способ позволяет добавлять в инфцию о типе свои данные за счет наследования от класса type_info. Указатель на объект type_info добавл в ТВФ. Этот способ удобен, когда у объектов нет общего интерфейса.
4. Применение операции динамич преобразования типа. dynamic_cast <T*>(p) или <T&>
p – полиморфный указатель или ссылка (объект р привожу к типу Т) (т.е. у объекта на кот указ д.б. вирт функ). Позволяет опрть реал тип полиморф объекта. Если преобрние к указму типу невозможно, то в случае с указателем возврся 0, со ссылкой – исключения bad_cast. Данная операция позволяет реалть понижающее преобразованиетипа downcast, что испся при оргции сериализации, и перекрестноеcrosscast – для перехода м/у альтернативными переходами

15. Шаблоны. Раздельная компиляция. Наследование шаблонов
Из ответов
Шаблоны семейство типов или функций имеющих единое параметризованное описание. Описание конкретного типа или фции генерируются по шаблону автоматически (инстанцированиепроцедура получения класса по шаблону). Результат – шаблонный класс или функция. Параметры шаблона – формальные. При инстанцировании – фактические. Виды параметров шаблона: тип; Объект (значение переменной). Такой параметр в теле шаблона считается константой. Не испся в шаблонных функций. Шаблон Раздельная компиляция. 2 подхода:
1)описание всего шаблона в заголовочных файлах. Иначе становятся недоступны при инстанцировании тела методов.
2)Раздел компиляция шаблонов. Реализация методов в отдел файле с ключ словом export:
в .h :
template <class T> void out (const T&t);
.cpp : #include “.h”
export template <class T> void out (const T&t)
Наследование шаблонов.
1)Базовый класс – обычный template < class T> class D : public B {T b}; 2)Базовый класс – шаблон template < class T> class B {T b}
template < class T> class D : public B <T> {…};
При инстанцировании будет сгенер большое колво шаблонных классов 3) Базовый класс шаблонный класс
template < class T> class B {T b}
template < class T1> class D : public B <int>{T1 d} class F : public D<double>{...};
Позволяет сократить колво автоматич сгенерир классов. 4)Базовый класс параметр шаблона
template < class T, class B2>
class D : public B, public B2 {…};
Позволяет организовать наследование от произвол класса пользователя.
В ряде библейских контейнеров, пострных на основе наследования, класс аллокатора подключался к контейнеру по этому способу наследования. сюрРррррреализация своего аллокатора позволяла обеспечить его фциями все
контейнеры. |
|
5) Передача произвольного класса базовому |
template < class C > class B{C b}; |
template < class T > class D : public B <D<T>> {…}; |
Испся когда в баз классе описаны операции общие для всех контейнеров, а производным явл обобщенный контейнер. Тогда для реализ некот операций необхм тип контейнера. Передачу типа обеспеч данный способ.
Выбор алгоритма через параметр шаблона Проблема – в том, что необх реалть алгм, крый работает поразному для разных типов данных. В кач примера рассм сортировку элтов вектора Способы:
1)Глобальный шаблон – функция сортировки + специализация частных случаев разными шаблонными функциями /общий подход/
2)Выделение вариантной части функции в отдельный класс /функц объект/ + специализация этого класса шаблонными классами и добавление класса наследованием + реализация глобальной функции сортировки, работающей с объектом, унаследованного класса
vector <T> <| SortTableVector<T> |> Comparator<T>
3)Добавление вариантной части в качве нового парра фции
template <class T> sort (vector<T>&v,Comparator <T>&cmp)
4) Добавление вариантной части в кач параметра шаблона. Такие парры шаблона назся свойства traits, интенсивно исп в STL наиболее универсальный подход. Недостаток – появл нового парра шаблона, но устраняется за счет значений парров по умолчанию <class T=cmp<T>>.
Вызов шаблонной фции м выпся: f( , ). проблема опрния парров шаблона для инстанцирования. В этой ситуации испся значения по умолч и делается попытка опрть парры шаблона по типам парра фции. Если нам не устраивает, м явно указать фактич парры при вызове фции: f<,>(,)
Параметры шаблоа по типам параметра функции template <class T> void sort(T* a); //сортировка массива а int* a = new int[10];
…
sort(a); //sort <int>(a), но в данном случае int определится автоматически
специализация шаблонов.
template < class T > class vector{…}; общий случай – просто шаблон template < > class vector <void*>{…}; Полная специализация //указ на void
template < class T > class vector <T*> {…}; частичная специализация (будет дейстть для указлей, кроме на void)
Шаблоны как параметры шаблонов если в теле шаблона класса их требуется инстанцировать с разными фактич параметров, иначе следует передавать типы или объекты
template <class T1> class B{ T1 b}; ///шаблонный класс template <class T2> class C{T2 c};
C<B <int> > obj; //шаблоны, как параметры шаблонов
Шаблоны функций – опрт потенцно бесконечное число совместно испмях шаблонных фций, инстанцирование крых выпся автоматически при каждом вызове фции или взятии ее адреса. При вызове фции если парр шаблона не м.б. выведен из типа парра фции следует испть ключ слово template : m.template get<int> ();
Методы шаблона неявно шаблонной функцииДрузьятакжешаблоннойфции,каждыйимеет свою копию. В классе м испть также членышаблоны. Они не м.б. виртуальными. В осн примся для реалции отношений м/у классами сгенерирми по одному шаблону.

16. Обработка исключительных ситуаций
Из ответов
Механизм ОИСобесп способ передачи упрния из точки, где ситуация была возбуждена, в точку, где уже было управление и выражено желание обрабатывать ситуацию данного типа. В С++ реал модель ОИС с завершением – после обработки нельзя вернуться в то место, где ситуация была возбуждена, и продолжить выполнение. ОИС ориентир на последоват выпние прмы, асинхронные – не контролся.
Особенности:
1.Возбуждение ИС реался конструкцией throw объект; создается объект с пом констр по умолч и передается в точку обработки ; throw; повторное возбуждение текущей ИС
try //возникает исключение
{
int a = 2; if(a<0)
throw a; // вызываю искление
else
throw;
}
catch(int i) // Поймать исклчение, для обработки, что бы программа не упала
{
std::cout << i;
}
catch()
{
}
class DerivedException : Exception {}
2.Для контроля ИС фрагмент прмы д. находиться вtry {фрагмент, где контрол ИС}список реализаций;
3.Реакция описывается в конструкции catch () {операторы реакции}.Каждая реация имеет семантику, схожую с вызовом фции с одним парром. catch (…)реакция на любую ИС. Порядок срабатывания реакции в конструкции try соотт порядку реакции в списке реакций. (если первым поставить catch(…), то след никогда не сраб).
Два описание мнва ИС создается сисма классов. Возмны 2 способа обработки ИС:
а)ООый. В базовом классе ИС описся виртуал фции,в произх – они переопрся; в списке реакций – ловится указатель на базовый класс; в теле реакции – работа с объектом осущся через виртуал фции
б) не ОО –ловится и обраб каждая ИС по отдельности.
4. Связь с конкретным классом реализуется с помощью вложенных классов. 5.Спецификация ИС. осущ указанием ключ слова throw после фции и перчисл типы: void f() throw(A,B); f возбуждает ИС A иВ; f() throw; любые ИС; f() throw();не возб ИС
6.Вирт фция не м.б. замещена в производ классе другой с не менее огрной спецификацией возбуждения ИС: B<D; B: f(), g() throw(X,Y), h() throw(X); D: f() throw(X), g()throw(X), h() throw(X,Y)ошне м увелич число ИС
Особые случаи при обработке исключительных ситуаций.
1.ИС, возникающие в конструкторе – вызываются деструкторы для всех полностью сконструир локальных объектов. Для самого объекта деструктор не вызывается.
2.ИС при конструировании подобъекта – не вызыв деструктор ни для объекта, ни для подобъекта.
3.Возбуждена ИС, но реакции нет. Тогда она ищется в охватывающем блоке try. Если нет вообще – возбуждается стандарт фция std::terminate, края по умолч вызывает стандартн фцию abort – аварийно завершает прму. В пом фции set_terminate м настроить terminate на вызов опрй фции.
4.Разрушен стек – terminate+abort.
5.Деструктор, вызванный при сворачивании стека изза ИС, сам возб. ИС
(terminate+abort)
6.Функция возбуждает неуказанную ИС. Вызывается стандарт фция std::unexpected, края по умолч вызывает terminat+abort. Set_unexpected настраивается на пользоват фция. Для борьбы с данной ситуацией м. добавить к спецификации ИС стандартную std::bad_exception – тогда при возбуждении неуказй ИС будет возбуждаться bad_exception. “”теряется инфа о первонач ИС.
Исключительные ситуации и потребление ресурсов.
Ресурс то, что м.б. занято и после испния д.б. освобождено. Пр: файл, буфер. 3 стадии использования ресурса: Получение, Использование, Освобождение.
В случае возникновения ИС на 2м этапе ресурсы могут оказаться неосвобожденными. Для решения этой проблемы создся класс, образующий функц замыкание вокруг ресурса: Получение рессов – с пом конструктора класса. Испние реалт методы, Деструтор – освобождает. Тогда при возб ИС на 2м этапе механизм гарантирует автоматич вызов деструктора.
Еще одна проблема истощение ресурсов – хотим получить ресурс, а его нет (чаще это память)
2 подхода:
1.Завершение (termination) ресурс закономерно возбуждает ИС. Вызывающий код должен быть готов к ситуации подобного типа.
2.Продолжение (recuption) при истощении ресурса делается попытка обращения к вызывающему коду. Если она не проходит, то происходит вызов ИС.