
- •5.Препроцессор. Директивы препроцессора.
- •7.Работа с файлами. Текстовый и двоичный режим.
- •8.Указатели. Адресная арифметика.
- •10.Перечислимый тип. Структуры. Объединения.
- •11.Поразрядные операции.
- •13.Спецификаторы класса памяти.
- •14.Пространства имён.
- •15.Компоновка. Правило одного определения.
- •16.Понятие класса.
- •17.Функции-члены класса. Указатель this.
- •18.Конструкторы. Деструкторы.
- •19.Преобразования объектов класса.
- •20.Доступ к членам класса.
- •21.Статические члены класса.
- •22.Друзья класса.
- •23.Совместное использование.
- •24.Перегрузка операций.
- •25.Шаблоны.
- •26.Обработка исключительных ситуаций.
- •27.Производные классы.
- •28.Виртуальные функции. Абстрактные классы.
- •29.Указатели на члены класса.
- •30.Множественное наследование.
- •31.Структура dll-библиотеки.
- •32.Статическое и динамическое подключение dll-библиотек.
- •34.Регистры процессора.
- •35.Использование стека. Команды работы со стеком в языке ассемблера.
- •36.Арифметические команды в языке ассемблера.
- •37.Команды сравнения и перехода в языке ассемблера.
- •38.Команды работы с битами в языке ассемблера.
- •39.Процедуры в языке ассемблера. Передача параметров в процедуру.
- •40.Процедуры в языке ассемблера. Возврат результата. Локальные данные.
19.Преобразования объектов класса.
Преобразования (изменения типа) объектов класса выполняются конструкторами и преобразующими функциями.
Такие преобразования, называемые пользовательскими, часто неявно применяются в дополнение к стандартным преобразованиям. Например, функция, ожидающая параметр типа Х, может вызываться не только с параметром типа Х, но и с параметром типа Т, если существует преобразование из Т в Х. Кроме того, пользовательские преобразования применяются для приведения инициализаторов, параметров функций, возвращаемых функциями значений, операндов в выражениях, управляющих выражений, операторах цикла ивыбора и для явного приведения типов.
Пользовательские преобразования применяются только там, где они однозначны.
Преобразование посредством конструктора Конструктор с одним параметром задаёт преобразование типа своего параметра к типу своего класса.
Конструктор с одним параметром не обязательно вызывается явно.
class X { private: int x; public: X(int n); ... }; X::X(int n) { x = n; } |
|
X a = 1; |
// Эквивалентно X a = X(1) |
Однако неявное преобразование может быть нежелательно в некоторых случаях.
class Str { private: char *str; public: Str(int n) { str = new char [n]; *str = 0; } Str(const char *p) { str = new char [strlen(p) + 1]; strcpy(str, p); } ~Str() { if (str) delete [] str; } };
|
|
Str s = 'a'; |
// Создание строки из int('a') элементов |
Неявное преобразование можно подавить, объявив конструктор с модификатором explicit. Такой конструктор будет вызваться только явно.
class Str { private: char *str; public: explicit Str(int n) { str = new char [n]; *str = 0; } Str(const char *p) { str = new char [strlen(p) + 1]; strcpy(str, p); } ~Str() { if (str) delete [] str; } }; |
|
Str s1 = 'a';
Str s2(10); |
// Ошибка – нет неявного преобразования char в Str // Правильно – создаётся строка из 10 символов |
Преобразующие функции Функция-член класса Х, имя которой имеет вид operator <имя типа>, определяет преобразование из Х в тип, заданный именем типа. Такие функции называются преобразующими функциями или функциями приведения.Для такой функции не могут быть заданы ни параметры, ни возвращаемый тип.
class X { private: int x; public: X(int n); operator int(); ... }; X::X(int n) { x = n; }
X::operator int() { return x; }
int a; X b(0); |
|
a = (int)b; |
// Явный вызов преобразующей функции |
a = b; |
// Неявный вызов преобразующей функции |
Разрешение неоднозначности Присваивание значения типа V объекту класса X допустимо в том случае, если имеется оператор присваивания X::operator= (Z) такой, что V является Z или существует единственное преобразование V в Z. Инициализация рассматривается аналогично. В некоторых случаях значение требуемого типа может быть создано при помощи повторного использования конструкторов или операторов преобразования. Это должно осуществляться при помощи явных преобразований – допустим только один уровень неявных преобразований, определяемых пользователем. В некоторых случаях значение требуемого типа может быть создано более чем одним способом – такое недопустимо.
Правила преобразования не являются ни самыми простыми для реализации из всех возможных, ни самыми легкими для документирования, ни настолько общими, как можно себе представить. Однако они довольно безопасны, и их применение не приводит к неприятным сюрпризам. Гораздо легче вручную разрешить неоднозначности, чем найти ошибку, вызванную преобразованием, о котором и не подозревали.