
- •Учебное пособие
- •Введение
- •Объектно-ориентированный подход
- •Объектно-ориентированное программирование Абстрактные типы данных
- •Базовые принципы объектно-ориентированного программирования
- •Простейший ввод и вывод
- •Объект cout
- •Манипуляторы hex и oct
- •Другие манипуляторы
- •Объект cin
- •Операторы для динамического выделения и освобождения памяти (new и delete)
- •Базовые конструкции объектно-ориентированных программ Объекты
- •Понятие класса
- •Конструктор копирования
- •Конструктор explicit
- •Указатели на компоненты класса
- •Встроенные функции (спецификатор inline)
- •Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •Вложенные классы
- •Static-члены (данные) класса
- •Указатель this
- •Компоненты-функции static и const
- •Proxi-классы
- •Параметры ссылки
- •Независимые ссылки
- •Практические приемы ограничения числа объектов класса
- •Наследование (производные классы)
- •Конструкторы и деструкторы при наследовании
- •Виртуальные функции
- •Абстрактные классы
- •Виртуальные деструкторы
- •Множественное наследование
- •Виртуальное наследование
- •Перегрузка функций
- •Перегрузка операторов
- •Перегрузка бинарного оператора
- •Перегрузка унарного оператора
- •Дружественная функция operator
- •Перегрузка оператора []
- •Перегрузка оператора ()
- •Перегрузка операторов new и delete
- •Преобразование типа
- •Явные преобразования типов
- •Преобразования типов, определенных в программе
- •Шаблоны Параметризированные классы
- •Передача в шаблон класса дополнительных параметров
- •Шаблоны функций
- •Совместное использование шаблонов и наследования
- •Шаблоны класса и friend
- •Некоторые примеры использования шаблона класса Реализация smart-указателя
- •Классы поддерживающие транзакции
- •Задание значений параметров класса по умолчанию
- •Пространства имен
- •Ключевое слово using как директива
- •Ключевое слово using как объявление
- •Псевдоним пространства имен
- •Организация ввода-вывода
- •Состояние потока
- •Строковые потоки
- •Организация работы с файлами
- •Организация файла последовательного доступа
- •Создание файла произвольного доступа
- •Основные функции классов ios, istream, ostream
- •Основы обработки исключительных ситуаций
- •Перенаправление исключительных ситуаций
- •Исключительная ситуация, генерируемая оператором new
- •Генерация исключений в конструкторах
- •Задание собственной функции завершения
- •Спецификации исключительных ситуаций
- •Задание собственного неожиданного обработчика
- •Иерархия исключений стандартной библиотеки
- •Стандартная библиотека шаблонов (stl) Общее понятие о контейнере
- •Общее понятие об итераторе
- •Категории итераторов
- •Основные итераторы
- •Вспомогательные итераторы
- •Операции с итераторами
- •Контейнерные классы Контейнеры последовательностей
- •Контейнер последовательностей vector
- •Контейнер последовательностей list
- •Контейнер последовательностей deque
- •Ассоциативные контейнеры
- •Ассоциативный контейнер multiset
- •Ассоциативный контейнер set
- •Ассоциативный контейнер multimap
- •Ассоциативный контейнер map
- •Адаптеры контейнеров
- •Адаптеры stack
- •Адаптеры queue
- •Адаптеры priority_queue
- •Пассивные и активные итераторы
- •Алгоритмы
- •Алгоритмы сортировки sort, partial_sort, sort_heap
- •Алгоритмы поиска find, find_if, find_end, binary_search
- •Алгоритмы fill, fill_n, generate и generate_n
- •Алгоритмы equal, mismatch и lexicographical_compare
- •Математические алгоритмы
- •Алгоритмы работы с множествами
- •Алгоритмы swap, iter_swap и swap_ranges
- •Алгоритмы copy, copy_backward, merge, unique и reverse
- •Примеры реализации контейнерных классов Связанные списки
- •Реализация односвязного списка
- •Реализация двусвязного списка
- •Реализация двоичного дерева
- •Литература
- •Вопросы по курсу ооп
- •220013, Минск, п.Бровки, 6.
Преобразования типов, определенных в программе
Конструктор с одним аргументом можно явно не вызывать.
#include "iostream.h"
class my_class
{ double x,y; //
public:
my_class(double X){x=X; y=x/3;}
double summa();
};
double my_class::summa() { return x+y; }
void main()
{ double d;
my_class my_obj1(15), // создание объекта obj1 и инициализация его
my_obj2=my_class(15), // создание объекта obj2 и инициализация его
my_obj3=15; // создание объекта obj3 и инициализация его
d=my_obj1; // error no operator defined which takes a right-hand operand of
// type 'class my_class' (or there is no acceptable conversion)
cout << my_obj1.summa() << endl;
cout << my_obj2.summa() << endl;
cout << my_obj3.summa() << endl;
}
В рассматриваемом примере все три создаваемых объекта будут инициализированы числом 15 (первые два явным, третий неявным вызовом конструктора). Следовательно, значение базовой переменной (определенной в языке) может быть присвоено переменной типа, определенного пользователем.
Для выполнения обратных преобразований, то есть от переменных, имеющих тип, определенный пользователем к базовому типу, можно задать преобразования с помощью соответствующей функции operator(), например:
class my_class
{ double x,y;
public:
operator double() {return x;}
my_class(double X){x=X; y=x/3;}
double summa();
};
Теперь в выражении d=my_obj1 не будет ошибки, так как мы задали прямое преобразование типа. При выполнении этой инструкции активизируется функция operator, преобразующая значение объекта к типу double и возвращающая значение компоненты объекта . Наряду с прямым преобразованием в С++ имеется подразумеваемое преобразование типа:
#include "iostream.h"
class my_cl1
{ double x; //
public:
operator double(){return x;}
my_cl1(double X) : x(X) {}
};
class my_cl2
{ double x; //
public:
operator double(){return x;}
my_cl2(my_cl1 XX): x(XX) {}
};
void fun(my_cl2 YY)
{ cout << YY <<endl; }
void main()
{ fun(12); // ERROR cannot convert parameter 1
// from 'const int' to 'class my_cl2'
fun(my_cl2(12)); // подразумеваемое преобразование типа
}
В этом случае для инструкции fun(my_cl2(12)) выполняется следующее:
активизируется конструктор класса my_cl1 (x инициализируется значением 12);
при выполнении в конструкторе my_cl2 инструкции x(XX) вызывается функция operator (класса my_cl1), возвращающая значение переменной x, преобразованное к типу double;
далее при выполнении инструкции cout << YY вызывается функция operator() класса my_cl2, выполняющая преобразование значения объекта YY к типу double.
Разрешается выполнять только одноуровневые подразумеваемые преобразования. В приведенном выше примере инструкция fun(12) соответствует двухуровневому неявному преобразованию, где первый уровень - my_cl1(12) и второй - my_cl2(my_cl1(12))
В заключение отметим основные правила доопределения операторов:
- все операторы языка С++ за исключением . * :: ?: sizeof и символов # ## можно доопределять;
- при вызове функции operator используется механизм перегрузки функций;
- количество операндов, которыми оперируют операторы (унарные, бинарные), и приоритет операций сохраняются и для доопределенных операторов.