Преобразование типов данных и классы
При работе со стандартными типами данных в Си имеют место явные и неявные преобразования их типов. По аналогии для классов также могут быть определены такие операции - они ассоциируются с конструированием объектов класса. Так, если в программе встречается преобразование типа (класса) "yyy" к типу (классу) "xxx", то для его осуществления в классе "xxx" необходим конструктор вида
xxx(yyy &);
Сами преобразования типов происходят в тех же самых случаях, что и обычные преобразования базовых типов данных:
-при использовании операции явного преобразования типов;
-при выполнении операции присваивания, если она не переопределена в виде " xxx=yyy" (транслятором создается временный объект класса " xxx", для которого вызывается указанный конструктор и который затем используется в правой части операции присваивания);
-при неявном преобразовании типа формального параметра функции при передаче его по значению (вместо конструктора копирования);
-при неявном преобразовании типа результата функции при передаче его по значению (вместо конструктора копирования);
-при определении объекта класса "xxx" одновременно с его инициализацией объектом класса "yyy" (вместо конструктора копирования)
yyy b;
xxx a = b;
При конструировании объекта класса "xxx" с использованием объекта класса "yyy" естественно должна быть обеспечена доступность необходимых данных последнего (например, через дружественность).
В качестве примера рассмотрим обратное преобразование базового типа long к типу dat -количество дней от начала летоисчисления преобразуется к дате. Здесь же рассмотрим другой класс - man , в котором одним из элементов личной части является дата. Значение этого объекта копируется при преобразовании типа man в тип dat .
//------------------------------------------------------bk73-08.cpp
//------ Преобразование переменной к объекту класса -------
static int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
class man;
class dat
{
int day,month,year;
public:
dat(long); // Преобразование long в dat
dat(man&); // Преобразование man в dat
dat() {}
};
class man
{
friend class dat;
dat WasBorn; // объект класса dat в объекте класса man
public:
man(dat&); // Преобразование dat в man
};
//------ Преобразование man в dat ----------------------
dat::dat(man& p)
{ *this = p.WasBorn; }
//------ Преобразование dat в man ------------------------
man::man(dat& p)
{ WasBorn = p; }
//------ Преобразование long в dat ----------------------
dat::dat(long p)
{
year = p / 365.25; // Число лет с учетом високосных
p-=(year-1)*365L - year/4; // Остаток дней в текущем году
year++; // Начальный год - 0001
for (month=1; p > 0; month++)
{ // Вычитание дней по месяцам
p -= days[month];
if (month == 2 && year % 4 == 0) p--;
}
month--; // Восстановление последнего месяца
p += days[month];
if (month == 2 && year % 4 == 0) p++;
day = p + 1;
}
// Преобразование объектов класса имеет место при выполнении
// операций явного приведения типов, присваивания, а также
// при определении объектов с инициализацией их объектами
// приводимого класса
long l=1000;
dat a = l, b; // Вызов конструктора dat(long)
man c = a; // Вызов конструктора man(dat&)
man f(man a)
{ return(a); }
void main()
{
a = 2000L; / / Вызов конструктора dat(long)
(dat)3000L; // Вызов конструктора dat(long)
c = b; // Вызов конструктора man(dat&)
b = f(b); // Вызов конструктора dat(man&) при преобразовании
// типа параметра. Вызов конструктора man(dat&)
} // при преобразовании типа результата