Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯМП ответы.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
710.66 Кб
Скачать

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. Инициализация рассматривается аналогично. В некоторых случаях значение требуемого типа может быть создано при помощи повторного использования конструкторов или операторов преобразования. Это должно осуществляться при помощи явных преобразований – допустим только один уровень неявных преобразований, определяемых пользователем. В некоторых случаях значение требуемого типа может быть создано более чем одним способом – такое недопустимо.

Правила преобразования не являются ни самыми простыми для реализации из всех возможных, ни самыми легкими для документирования, ни настолько общими, как можно себе представить. Однако они довольно безопасны, и их применение не приводит к неприятным сюрпризам. Гораздо легче вручную разрешить неоднозначности, чем найти ошибку, вызванную преобразованием, о котором и не подозревали.