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

15.3. Класс на базе объединения

Не так уж и часто для создания класса используют объединения. Один из таких редких примеров описан в книге Г. Шилдта "Теория и практика C++". СПб.: БХВ-Петербург, 2000, – 416 с. Он относится к узко специализированному классу, который выводит в двоичном виде все байты вещественного числа типа double.

#include <iostream.h>

#include <conio.h>

union bits {

double d; //первое данное

unsigned char c[sizeof(double)]; //совмещаемый массив

bits(double n); //конструктор инициализации

void show_bits(); //отображение байтов d

};

bits::bits(double n) {d=n;}

void bits::show_bits()

{ int i,j;

for(j=sizeof(double)-1; j>=0; j--)

{ cout<<"Byte "<<j<<": ";

for(i=128; i; i>>=1)

if(i & c[j]) cout << "1";

else cout<< "0";

cout<<"\n";

}

}

void main()

{ bits qq(2006.0203);

qq.show_bits();

getch();

}

//=== Результат работы ===

Byte 7: 01000000

Byte 6: 10011111

Byte 5: 01011000

Byte 4: 00010100

Byte 3: 11001001

Byte 2: 10000101

Byte 1: 11110000

Byte 0: 01101111

На что в этом примере можно обратить внимание. Во-первых, на организацию цикла по i. Начальное значение управляющей переменной в этом цикле представлено единицей в восьмом разряде. При очередном повторении цикла эта единица сдвигается вправо на один бит и используется для проверки соответствующего разряда в очередном байте массива c. Во-вторых, в приведенном классе отсутствуют указания о правах доступа. Для объединения это означает, что все члены класса являются общедоступными (в частности, это одно из немногих отличий между классами, созданными с использованием union, от настоящих классов, создаваемых с помощью class). Классы, создаваемые на базе объединений, имеют ряд ограничений. В них, например, не могут использоваться статические и виртуальные функции.

15.4. Новые типы данных на базе перечисления

Еще реже для создания новых типов данных в языке C++ используют перечисления. Один из таких примеров приведен в книге В.Лаптева. Он связан с "наведением порядка" в перечислении Decade, где для обозначения цифр от 0 до 9 использованы их английские эквиваленты. Новый порядок разрешает пользователю складывать элементы этого "множества" по модулю 10, производить сложения элементов перечисления с целыми числами (по тому же модулю 10), выводить значения переменных типа Decade словами. Ниже приводится полный текст файла decade.h, содержащего описание класса и тексты всех его внешних функций:

#ifndef _DECADE_H

#define _DECADE_H

//Объявление нового типа данных

enum Decade {zero,one,two,three,four,five,six,seven,eight,nine};

//Переопределение операции +

Decade operator+(const Decade &a, const Decade &b)

{ return Decade((int(a)+int(b))%10); }

//Переопределение операции +=

Decade operator+=(Decade &a, const Decade &b)

{ return a=Decade(int(a+b) % 10); }

//Переопределение операции ++a

Decade operator++(Decade &a)

{ a=Decade((int(a)+1) % 10); return a; }

//Переопределение операции a++

Decade operator++( Decade &a,int)

{ Decade t=a;

a=Decade((int(a)+1) % 10); return Decade(t); }

//Переопределение операции <<

ostream& operator<<(ostream &out, const Decade &a)

{ char *s[]={"zero","one","two","three","four","five","six","seven",

"eight","nine"};

out<<s[a]; return out; }

//Переопределение операции Decade+int

Decade operator+(const Decade &a, const int b)

{ int t= ((int)a + b) % 10;

return Decade(t); }

//Переопределение операции int+Decade

Decade operator+(const int a, const Decade &b)

{ return Decade((a+int(b)) % 10); }

#endif

Программа тестирования новой декады и результаты ее работы приведены ниже:

#include <iostream.h>

#include <conio.h>

#include "decade.h"

void main()

{ Decade A=seven,B=six;

cout<<"A="<<A<<endl; //Результат A=seven

cout<<"B="<<B<<endl; //Результат B=six

cout<<"A+B="<<A+B<<endl; //Результат A+B=three

A += B;

cout<<"A="<<A<<endl; //Результат A=three

++A;

cout<<"A="<<A<<endl; //Результат A=four

A++;

cout<<"A="<<A<<endl; //Результат A=five

B=A+6;

cout<<"B="<<B<<endl; //Результат B=one

A=3+B;

cout<<"A="<<A<<endl; //Результат A=four

getch();

}

Приведенный пример, конечно, носит только учебный характер. Как такового полноценного класса с объединением данных и обрабатывающих функций в единый блок здесь нет. Собственно и синтаксис перечисления не позволяет включить в фигурные скобки ничего кроме списка символьных констант. Но этот пример демонстрирует возможность "обучения " компилятора процедурам обработки новых данных, которые выглядят в программе достаточно привычно для человека.