Преобразование, определяемые классом

Операция преобразования типов предоставляет механизм явного преобразования объектов данного класса в другой тип.

Явное преобразование типов выражения применяется тогда, когда неявное преобразование нежелательно или когда без него выражение недопустимо. Одна из задач С++ - интеграция Абстрактного Типа Данных (АТД) и встроенных типов. Чтобы достигнуть этого существует механизм функции-члена, обеспечивающей явное преобразование. Функциональная запись:

Имя типа (выражение)

эквивалентна приведению. Тип должен быть выражаем как идентификатор. Таким образом два выражения
x=(float)i;
x=float(i);
эквивалентны. Выражение
p=(int *)x; // допустимое приведение
не может непосредственно функционально выражаться как
p=int *(x);
Однако, для этого может использоваться typedef
typedef int * int_ptr;
p=int_ptr(x);
Конструктор с одним аргументом фактически представляет собой преобразование из типа аргумента к типу конструируемого класса.

string(const char *p) { len=strlen(p); s=new char[len+1]; strcpy(s,p); }

Представленное выражение - автоматическое преобразование типов от char * к string. Оно доступно как явно, так и неявно. Явно оно используется или как операция преобразования, или в приведении, или в функциональной форме. Таким образом, возможны два рабочих варианта кода:
string s;
char * logo=” Hello”;
s=string(logo); // выполняет преобразование, затем присвоение
и
s=logo; // неявный вызов преобразования
Данный код - преобразование из уже определенного типа к типу, определяемому пользователем. Однако, пользователь не может добавлять конструкторы встроенных типов, таких как int. Может возникнуть необходимость в преобразовании из string в char *, что может быть выполнено с помощью определения специальной функции преобразования внутри класса string следующим образом:

operator char * () { return s; }

Общая форма записи такой функции-члена

operator тип() {...}

Такая функция преобразования должна быть нестатической функцией-членом без возвращаемого типа и с пустым списком аргументов. Преобразование происходит неявно в выражениях присвоения, при передаче параметров функциям, и в значениях, возвращаемых функциями.
Преобразующая функция-член в форме A::operator B() и конструктор в форме B::B(const A&) обеспечивает преобразование из типов объекта A в тип объекта B.
Неявное преобразование типов происходит тогда, когда имеется конструктор преобразования данного типа в объект класса:
Int int1,int2; int2=int1+6;
Если класс содержит конструктор с одним параметром вида:
Int::Int(int a) { b=a; },
то код будет работать нормально, если же нет, то будет ошибка.
Int int1,int2; int2=6+int1;
Запись такого вида недопустима. Она означает:. передать объекту 6 сообщение +с параметром int1. Возможно ли, обеспечить такую запись. Да, если написать перегруженный оператор + как дружественные функции.
Рассмотрим преобразование объектов одного класса в объекты другого класса. Если мы хотим преобразовать объект класса OldType в объект класса NewType, то класс NewType должен иметь конструктор с параметром типа OldType или OldType&:
class OldType{
};
class NewType {
public:
NewType(void) {}
NewType(OldType &old) { }
};
void main() {
OldType oldtype;
NewType newtype=oldtype;
}
либо с использованием операции преобразования типов
operator NewType(void);
class NewType {
public:
NewType(void) {}
};
class OldType {
publci:
operator NewType() { return NewType(); }
};
void main() {
OldType oldtype;
NewType newtype=oldtype;
}
Использование одновременно конструктора и перегрузку операции приведение невозможно.
Так как, операции преобразования не имеют ни явных аргументов, ни возвращаемого значения, то они не могут быть перегружены. Может быть несколько операторов преобразования для различных типов. Операции преобразования наследуются и могут быть виртуальными.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: