- •6Vpj7-h3cxh-hbtpt-x4t74-3yvy7
- •Оглавление
- •Предисловие
- •Введение
- •1.1. Понятие класса и объекта. Инкапсуляция
- •1.2. Определение классов. Компоненты. Доступность
- •Class_key /*class_id*/ { /*members_list*/ };
- •Value_type class_id::function_id(parameters) {statements}
- •CPoint point1(100,70); // локальный объект
- •Static cPoint point3(50,120); // статический объект
- •Class_id(parameters) /*:initializer_list*/ {/*statements*/}
- •CString(const char *);
- •Delete[] __thematrix;
- •1.4. Обращение к компонентам объектов
- •1.5. Статические и нестатические компоненты классов
- •1.7. Указатель this
- •В опросы для самопроверки
- •2. Механизм наследования. Полиморфизм
- •2.1. Формы наследования. Базовые и производные классы
- •Class_key class_id: inheritance_specifier base_class_id {member_list};
- •2.3. Абстрактные классы
- •2.4. Множественное наследование и виртуальные классы
- •2.5. Преобразование динамических типов. Динамическая идентификация типов
- •Catch ( std::bad_cast & ) { // обработка исключения
- •Return 0;
- •Вопросы для самопроверки
- •3. Дружественные функции и классы
- •3.1. Дружественные функции
- •3.2. Дружественные классы
- •Вопросы для самопроверки
- •4. Механизм вложения
- •4.1. Вложенные классы
- •4.2. Локальные классы
- •Вопросы для самопроверки
- •5. Объектная модель и шаблоны
- •5.1. Определение, описание и инстанцирование шаблонов
- •::Function_id(function_parameter_list) { statements }
- •5.2. Параметры и аргументы шаблонов
- •Class identifier typename identifier
- •// Key, Data – параметры-типы (типы ключа и данных отображения)
- •// Container – контейнер, где содержится информация отображения class сMap {
- •Class MyTemplate
- •Int array[10]; struct Structure { int m; static int sm; } str;
- •5.3. Шаблоны компонентных функций
- •Value_type function_template_id(function_parameter_list) { statements }
- •::Function_template_id(function_parameter_list) { statements }
- •5.4. Специализация шаблонов
- •Вопросы для самопроверки
- •6. Перегрузка операций
- •Value_type operator @ (parameter_list);
- •Value_type operator @ (parameter_list) { statements }
- •Return fail();
- •6.3. Перегрузка бинарных операций
- •Value_type operator @ (parameter); // компонентная функция
- •Value_type operator @ (parameter, parameter); // глобальная функция friend value_type operator @ (parameter, parameter); // дружественная функция
- •Return *this;
- •Return *this;
- •/* Присваиваем собственные данные класса d */
- •6.4. Перегрузка операций управления памятью
- •Typedef void (*new_handler) ();
- •Extern new_handler set_new_handler( new_handler new_p );
- •Void operator delete(void * memory) {
- •... // Специальная обработка пользователя ::operator delete(memory); // освободить память
- •Вопросы для самопроверки
- •7. Механизм исключений
- •Throw expression
- •7.3. Специальные средства поддержки механизма исключений
- •Unexpected_function set_unexpected(unexpected_function func_name);
- •Typedef void (* unexpected_function) ();
- •Extern char * __throwExceptionName; extern char * __throwFileName; extern unsigned __throwLineNumber;
- •Вопросы для самопроверки
- •8. Подсчет ссылок
- •8.1. Назначение механизма подсчета ссылок
- •8.2. Контекстно-независимая модель счетчика ссылок
- •8.4. Внедрение подсчета ссылок в существующий класс
- •Вопросы для самопроверки
- •9. Стандартная библиотека шаблонов (stl)
- •9.1. Назначение и архитектура stl
- •9.2. Последовательные контейнеры
- •Class vector {
- •// Определение итераторов
- •Sort(first,last); // сортировка вектора в диапазоне итераторов
- •Ifstream ifile ("example.In"); ofstream ofile ("example.Out");
- •OutputIterator copy(
- •InputIterator first, InputIterator last, OutputIterator result );
- •// Заполнение списка
- •Operator- (int)
- •Operator- (random access iterator) operator[] (int)
- •InputIterator find(InputIterator first, InputIterator last, const t & value);
- •InputIterator find(InputIterator first, InputIterator last, const t & value)
- •Return first;
- •OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
- •Return result;
- •OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op)
- •Return result;
- •Void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
- •__Quick_sort_loop(first, last, comp); __final_insertion_sort(first, last, comp);
- •T accumulate(InputIterator first, InputIterator last, t init, Function f);
- •V.Push_back(2); V.Push_back(5);
- •9.5. Функторы
- •T operator()(const t & X) const { return -X; }
- •9.7. Адаптеры
- •S1.Push(1); s1.Push(5);
- •// Записать в вектор числа 1 2 3 4
- •// Сортировать по неубыванию
- •// Записать в вектор числа 4 6 10 3 13 2
- •Вопросы для самопроверки
- •Заключение
- •Библиографический Список
- •6Vpj7-h3cxh-hbtpt-x4t74-3yvy7
Void operator delete(void * memory) {
if(memory == 0) return; // для нулевого указателя ничего не делать
... // Специальная обработка пользователя ::operator delete(memory); // освободить память
...
}
Операция operator delete[] перегружается аналогично, но, как и operator new[], характеризуется жесткими ограничениями.
Вопросы для самопроверки
Опишите сущность механизма перегрузки стандартных операций.
Перечислите основные ограничения перегрузки операций.
Как можно определить функцию-операцию по отношению к классу, для которого выполняется перегрузка операции?
Как должен в общем виде выглядеть прототип функции-операции, перегружающей префиксную унарную операцию?
Почему операцию = невозможно перегрузить глобальной функцией? Обоснуйте ответ.
Прототип функции-операции, суммирующей две матрицы, имеет вид const Matrix & operator + (const Matrix & m2) const; Какая в нем имеется ошибка и каковы ее потенциальные последствия?
Прототип функции-операции присваивания, определенной для класса матриц, имеет вид Matrix & operator = (const Matrix & m) const; Какого рода ошибка содержится в приведенном прототипе?
Требуется реализовать операцию суммирования матриц класса CMatrix с вещественным выражением с сохранением свойства коммутативности операции. Как следует определить эту функцию-операцию? Дайте эскиз определения.
Как правильно построить заголовок функции-операции operator –, которая изменяет знак всех элементов матриц класса CMatrix на противоположный?
Почему функция operator = в общем случае должна проверять присваивание объекта самому себе? Когда такая проверка избыточна?
Опишите алгоритм работы функции operator =, если класс, для которого она перегружена, является производным от другого класса.
Пусть для класса CRationalNumber, представляющего рациональные числа, требуется определить функцию operator <<. Как это сделать наиболее грамотно?
Как правильно задать заголовок функции operator <<, чтобы были возможны операторы вида cout << m1 << m2 << m3, где m1,m2,m3 – объекты класса, для которого определяется функция operator<< ?
Можно ли операцию [] перегрузить дружественной функцией? Поясните ответ.
Почему операция operator [] обычно перегружается дважды?
В классе Matrix, описывающем прямоугольные матрицы, имеется функция const Matrix operator + (double r) const; Она увеличивает элементы матрицы на выражение r. Можно ли этой функцией вычислить выражение 0.5+m? Обоснуйте ответ.
Программа содержит оператор m1 = m1 + m2, где m1 и m2 – объекты некоторого класса C, для которого перегружены операции = и +. Перепишите этот оператор в эквивалентной функциональной форме.
Чем отличаются заголовки функций-операций пре-инкремента (++c) и постинкремента (c++)?
Почему функция-операция префиксного декремента (--c) должна возвращать ссылку на класс? Обоснуйте ответ.
Заголовок операции суммирования, определенной для класса матриц, имеет вид: virtual const Matrix operator + (const Matrix & m2) const; Как правильно переопределить эту операцию в производном классе, например, поименованных матриц? Приведите только заголовок и обоснуйте выбранный вариант.
В базовом классе BasicMatrix, представляющем матрицы, определена операция вывода в поток с заголовком: friend ostream & operator << (ostream & stream, const BasicMatrix & m); От класса BasicMatrix порожден производный класс NamedMatrix, описывающий поименованные матрицы. Как наиболее рационально реализовать операцию записи в поток для этого производного класса?
Для класса NamedMatrix, являющегося производным от класса Matrix, определена операция чтения из потока: istream & operator >> (istream & stream, Matrix & m) { return stream >> dynamic_cast<Matrix &>(m); } Какого рода ошибка есть в этом определении? Каковы “симптомы” ее проявления?
В классе, представляющем двоичные векторы BoolVector, определена операция индексации с заголовками bool & operator [] (int i); (вариант 1) и const bool operator [] (int i) const; (вариант 2). Какой из вариантов операции будет использован в операторе cout<<v[i], если вектор v определен как неконстантный объект класса BoolVector? Обоснуйте ответ.
В классе, представляющем двоичные векторы BoolVector, определена операция с заголовком const BoolVector & operator | (const BoolVector & v) const; обеспечивающая поэлементное ИЛИ над векторами-операндами. Какого рода ошибка заключена в приведенном заголовке?
Запишите заголовок функции-операции явного преобразования объекта класса CClass2 в ранее определенный класс CClass1.
Чем вызвана невозможность корректной перегрузки операций && и ||? Почему операции & и | в отличие от первых двух можно легко перегрузить корректно? Дайте обоснование.
Приведите пример определения класса функциональных объектов (функторов).
Имеется прототип функции-операции: double operator () (double, double, double, ...)? Покажите как можно вызвать эту функцию.
В классе функторов CRandomGenerator (генератор случайных чисел с равномерным распределением на отрезке [a,b]) определена лишь одна следующая операция: double operator () (double a, double b) { randomize(); return a + fabs(b - a) * random(10000) / 10000; } Как воспользоваться функциональностью этого класса в программе (получить случайное число)? Приведите фрагмент кода.
Каким образом можно перегрузить функцию operator new? Опишите общие принципы перегрузки.
В чем состоит отличие между операциями new и operator new, delete и operator delete?
Как можно установить специальный обработчик ошибок выделения памяти операцией new? Ответ поясните примером.
В программе есть оператор вида CNamedArray * parr = new (MyNewHandlerFunc) CNamedArray("array", array, sizeof(array)/sizeof(array[0])); Он создает в динамической памяти объект класса CNamedArray (поименованный массив). Что представляет из себя имя MyNewHandlerFunc и как должна выглядеть его декларация?
Задачи
Решить задачи 1, 2 главы 5, используя возможности механизма перегрузки операций38. Использовать по возможности как компонентные, так и глобальные функции-операции.
