- •1. Комментарии
- •2. Константы
- •3. Встраиваемые функции Встраиваемые функции
- •4. Объявление структур, объединений и перечислений
- •5. Объявление переменных
- •5. Ссылки Что такое ссылка и что с ней можно делать
- •Ссылку можно рассматривать как еще одно имя объекта. В основном ссылки используются для задания параметров и возвращаемых функциями значений, а также для перегрузки операций.
- •6. Использование спецификатора void
- •7. Преобразование стандартных типов данных.
- •8. Новые операции new, delete, операция расширения области видимости
- •1. Операция new
- •2. Операция delete
- •3. Операция :: области видимости
- •9. Объявление функций. Аргументы по умолчанию
- •10. Перегрузка функций
- •Когда использовать перегрузку
- •Новые возможности по сравнению с Си
- •Объектно-ориентированные особенности языка
- •Две роли классов
- •Поля класса
- •Конструкторы класса
- •13. Перегрузка операций
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •14. Дружественные функции
- •15. Сходства и различия классов, структур и объединений.
- •Отличия структур и объединений от классов
- •16. Классы и объекты. Определение класса и области видимости. Опережающее объявление класса
- •Две роли классов
- •Поля класса
- •17. Использование спецификатора класса памяти static. Статические компоненты класса
- •18. Константные объекты и константные методы
- •19. Неявный указатель this
- •20. Указатели на член класса
- •21. Локальные и вложенные классы
- •22. Специальный вид методов класса - конструкторы и деструкторы. Некоторые особенности конструкторов и деструкторов Конструкторы класса
- •23. Классы, содержащие объекты других классов
- •24. Создание объектов с различным временем жизни
- •25. Массивы объектов класса
- •26. Особенности копирования объектов Конструктор копирования
- •27. Заготовка класса без наследников
- •28. Пример вектора с неповерхностным копированием.
- •29. Излишнее копирование. Конструктор копии. Операции присваивания.
- •1. Излишнее копирование
- •2. Конструктор копирования
- •3. Операции присваивания
- •30. Преобразование типов. Стандартные преобразования. Явное преобразование типов
- •Преобразования указателей и ссылок
- •Явные преобразования типов
- •Неявное преобразование типа
- •31. Преобразования абстрактных типов данных (преобразование типов данных, созданных программистом)
- •32. Наследование классов
- •33. Доступ к наследуемым членам класса
- •34. Стандартные преобразования типов при наследовании
- •35. Инициализация объекта порожденного класса. Конструктор копии. Операция присваивания.
- •3. Операции присваивания
- •37. Виртуальные функции. Объявления виртуальных функций. Чисто виртуальные функции
- •Методы(функции)
- •38. Таблица виртуальных функций. Случаи, когда вызов виртуальной функции не будет виртуальным. Виртуальные деструкторы
- •39. Ввод-вывод файлов. Потоки ввода-вывода. Библиотека ввода-вывода (iostream). Группы классов библиотеки ввода вывода
- •40. Краткая характеристика иерархии классов производных от conbuf.
- •Класс conbuf (constrea.H)
- •Функции-элементы
- •41. Иерархия классов производных от ios
- •42. Состояния потока. Ошибки потоков. Состояние потока
- •С каждым потоком связан набор флагов, которые управляют форматированием потока. Они представляют собой битовые маски, которые определены в классе ios как данные перечисления. Манипуляторы
- •Шаблоны и наследование. Шаблоны и конфигурация компиляторов. Достоинства и недостатки шаблонов.
- •Совместное использование шаблонов и наследования
- •Достоинства и недостатки шаблонов
- •Исключения Применение try, catch, throw
- •47. Обработка исключительных ситуаций. Обработка завершения. Обработка структурных исключений, заявление исключения, фильтрующие выражение. Исключительные ситуации
- •Обработка исключительных ситуаций
- •Обработчик завершения
- •48. Стратегии взаимодействия объектов в программе. Программа как система взаимодействующих объектов. Система объектов, управляемых сообщениями
- •1. Программа, как система взаимодействия объектов.
- •49. Элементы объектно-ориентированного анализа и объектно-ориентированного проектирования. Диаграммы классов. Отношения классов: ассоциация, наследование, агрегация, использование.
- •51. Элементы объектно-ориентированного анализа и объектно-ориентированного проектирования. Диаграммы объектов, назначения, отношения между объектами. Диаграммы объектов (object diagrams)
Преобразования указателей и ссылок
При работе с указателями и ссылками компилятор автоматически выполняет только два вида преобразований.
Если имеется указатель или ссылка на производный тип, а требуется, соответственно, указатель или ссылка на базовый тип.
Если имеется указатель или ссылка на изменяемый объект, а требуется указатель или ссылка на неизменяемый объект того же типа.
size_t strlen(const char* s);
// прототип функции
class A { };
class B : public A { };
char* cp;
strlen(cp);
// автоматическое преобразование из
// char* в const char*
B* bObj = new B;
// преобразование из указателя на производный класс
A* aObj = bObj;
// к указателю на базовый класс
Если требуются какие-то другие преобразования, их необходимо указывать явно, но в этом случае вся ответственность за правильность преобразования лежит на программисте.
Явные преобразования типов
Если перед выражением указать имя типа в круглых скобках, то значение выражения будет преобразовано к указанному типу:
double x = (double)1;
void* addr;
Complex* cptr = (Complex*) addr;
Такие преобразования типов использовались в языке Си. Их основным недостатком является полное отсутствие контроля. Явные преобразования типов традиционно использовались в программах на языке Си и, к сожалению, продолжают использоваться в Си++, что приводит и к ошибкам, и к путанице в программах. В большинстве своем ошибок в Си++ можно избежать. Тем не менее, иногда явные преобразования типов необходимы.
Для того чтобы преобразовывать типы, хотя бы с минимальным контролем, можно записать
static_cast < тип > (выражение)
Операция static_cast позволяет преобразовывать типы, основываясь лишь на сведениях о типах выражений, известных во время компиляции. Иными словами, static_cast не проверяет типы выражений во время выполнения. С одной стороны, это возлагает на программиста большую ответственность, а с другой — ускоряет выполнение программ. С помощью static_cast можно выполнять как стандартные преобразования, так и нестандартные. Операция static_cast позволяет преобразовывать типы, связанные отношением наследования, указатель к указателю, один числовой тип к другому, перечислимое значение к целому. В частности, с помощью операции static_cast можно преобразовывать не только указатель на производный класс к базовому классу, но и указатель на базовый класс к производному, что в общем случае небезопасно.
Однако попытка преобразовать целое число к указателю приведет к ошибке компиляции. Если все же необходимо преобразовать совершенно не связанные между собой типы, можно вместо static_cast записать reinterpret_cast:
void* addr;
int* intPtr = static_cast < int* > (addr);
Complex* cPtr = reinterpret_cast <
Complex* > (2000);
Если необходимо ограниченное преобразование типа, которое только преобразует неизменяемый тип к изменяемому (убирает описатель const), можно воспользоваться операцией const_cast:
const char* addr1;
char* addr2 = const_cast < char* > addr1;
Использование static_cast, const_cast и reinterpret_cast вместо явного преобразования в форме (тип) имеет существенные преимущества. Во-первых, можно всегда применить "минимальное" преобразование, т. е. преобразование, которое меньше всего изменяет тип. Во-вторых, все преобразования можно легко обнаружить в программе. В-третьих, легче распознать намерения программиста, что важно при модификации программы. Сразу можно будет отличить неконтролируемое преобразование от преобразования неизменяемого указателя к изменяемому.