Методические указания Ухта 2006 удк 681 06(076) г 23

Вид материалаМетодические указания
Приложение 4. Текст заголовка класса Address (файл Address.h)
Приложение 5. Тексты членов – функций класса Address (файл Address.cpp)
Приложение 6. Текст тестирующей класс Address программы
Подобный материал:
1   2   3   4   5   6

Приложение 4. Текст заголовка класса Address (файл Address.h)



/* заголовок класса Address:

это нетипизированный указатель в стиле языка PL/1.

Гатин Г.Н. 01.04.2004

*/

#include

#include


union AD {

double * pD;

float * pF;

int * pI;

char * PAD;

void * pVac;

unsigned int Dis;

};

// из структуры этого union проглядывает основная идея:

// Если нам захочется ссылаться на некоторый экзотический

// тип, надо только добавить указатель на него в этот

// union и, конечно же, остальные программки

class Address

{

AD pointer; // собственно указатель!

int How; // длинна типа на который ссылается наш тип

public:

Address () { pointer.PAD = NULL; How = 0;}

// строки сохранены для большей ясности - то есть в

// учебных целях. так могли выглядеть конструкторы при

// отсутствии шаблонов

/*

Address (double * p) { pointer.pD = p;
How = sizeof(double); }

Address (float * p) { pointer.pF = p;

How = sizeof(float); }

Address (int * p) { pointer.pI = p; How = sizeof(int); } Address (char * p) { pointer.PAD = p; How = sizeof(char); }

*/

//template <class T> Address (T * p) {pointer.pVac = p;
How = sizeof(T); }

/*

Address (double & u) { pointer.pD = &u; How =
sizeof(double); }

Address (float & u) { pointer.pF = &u;
How = sizeof(float); }

Address (int & u) { pointer.pI = &u; How = sizeof(int); }

Address (char & u) { pointer.PAD = &u;
How = sizeof(char); }

*/

template <class T> Address (T & u) { pointer.pVac = &u;
How = sizeof(T); }

template <class T> Address (T & u, int k) {
pointer.pVac = &u;

if (k > 0) How = k;
else How = sizeof(T); }

// программы присвоения
/*

Address & operator = (double * p) { pointer.pD = p;
How = sizeof(double);
return (Address &)this; }

Address & operator = (float * p) { pointer.pF = p;

How = sizeof(float);

return (Address &)this; }

Address & operator = (int * p) { pointer.pI = p;

How = sizeof(int);

return (Address &)this; }

Address & operator = (char * p) { pointer.PAD = p;

How = sizeof(char);

return (Address &)this; }

*/

template <class T> Address & operator = (T & u) {
pointer.pVac = &u; How = sizeof(T);

return (Address &)this; }


void NULLa () { pointer.PAD = NULL; How = 0;}

// программа возвращения "длины типа" на который ссылается // наш адресс!

int LenType () { return How; }

// программа установки "длины типа" на который ссылается // наш адресс!

void SetLen (int f) { if (f > 0) How = f; }


// программы преобразования типа

operator double * () { return pointer.pD; }

operator float * () { return pointer.pF; }

operator int * () { return pointer.pI; }

operator char * () { return pointer.PAD; }

operator unsigned int () { return pointer.Dis; }

// принципиально это преобразование необходимо только для // печати!

// хотя как знать

operator AnsiString ();


// программы получения значения по адресу

double operator >> (double u) { return *pointer.pD; }

float operator >> (float u) { return *pointer.pF; }

int operator >> (int u) { return *pointer.pI; }

char operator >> (char u) { return *pointer.PAD; }

friend double operator << (double & u, Address a);

friend float operator << (float & u, Address a);

friend int operator << (int & u, Address a);

friend char operator << (char & u, Address a);

// программы копирования содержимого одного адреса в // другой

Address & operator >> (Address & a);

Address & operator << (Address & a);

// программы сравнения

bool operator == (Address & a) {

if (pointer.PAD == a.pointer.PAD) return true;

else return false;

}

bool operator != (Address & a) {

if (pointer.PAD != a.pointer.PAD) return true;

else return false;

}

bool operator < (Address & a) {

if (pointer.PAD < a.pointer.PAD) return true;

else return false;

}

// перегрузка операторов арифметики

Address operator + (int i) { Address temp;

temp.pointer.PAD = pointer.PAD + i;

return temp; }

Address operator - (int i) { Address temp;

temp.pointer.PAD = pointer.PAD - i;

return temp; }


friend Address operator + (int i, Address a) {
Address temp;

temp.pointer.PAD = i + a.pointer.PAD;

return temp; }

// интересно, что эту левостороннюю операцию транслятор на // дух не переносит: указатель не может быть
// отрицательным!!!
// только реально, сталкиваясь с этими вещами, начинаешь // глубже понимать
// С++ в частности и программирование вообще!

/*

friend Address operator - (int i, Address a) {

Address temp;

temp.pointer.PAD = i - a.pointer.PAD;

return temp; }

*/

// комментарии сохранены для более лучщего понимания сути.

// заменим предыдущую операцию немного другой! По сути
// делающей то же самое.

friend Address operator - (int i, Address a) {
Address temp;

temp.pointer.PAD = a.pointer.PAD - i;

return temp; }

Address operator ++ () {
Address temp;

temp.pointer.PAD = pointer.PAD;

++temp.pointer.PAD;

return temp; }

Address operator ++ (int i) {
Address temp;

temp.pointer.PAD = pointer.PAD;

temp.pointer.PAD++;

return temp; }

Address operator -- () {
Address temp;

temp.pointer.PAD = pointer.PAD;

--temp.pointer.PAD;

return temp; }

Address operator -- (int i) {
Address temp;

temp.pointer.PAD = pointer.PAD;

temp.pointer.PAD--;

return temp; }


int operator + (Address a) { int u;

u = pointer.Dis + a.pointer.Dis;

return u; }

int operator - (Address a) { int u;

__int64 c, b;

c = pointer.Dis; b = a.pointer.Dis;

u = c - b;

return u;

}

// программа копирования одной области памяти в другую
// Гатин Г.Н. 15.04.2004

bool copyMem (Address & a, int I);

template <class T> bool copyMem (T & Obj);

// программа сравнивания одной области памяти с другой Гатин Г.Н. 15.04.2004

int compareMem (Address & a, int I);


};


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

template <class T> class Aty {

T * p;

int How;

public:

template <class T> Aty () { p = NULL; How = 0; }

template <class T> Aty (T * u) { p = u; How = sizeof(T); }

template <class T> Aty (T & u) { p = &u; How = sizeof(T); }

template <class T> Aty & operator = (T & u) { p = u; How = sizeof(T);

return (Aty &)*this; }

};

Приложение 5. Тексты членов – функций класса Address (файл Address.cpp)



/* некоторые "длинные" программы для типа Address;

Гатин Г.Н. 02.04.2004

*/


// принципиально это преобразование необходимо только для печати!

Address::operator AnsiString ()

{

char buf[20];

sprintf (buf, "%p", pointer.PAD);

return (AnsiString) buf;

}


// программы перегрузки левосторонних операций

double operator << (double & u, Address a)

{ return *(a.pointer.pD); }

float operator << (float & u, Address a)

{ return *(a.pointer.pD); }

int operator << (int & u, Address a)

{ return *(a.pointer.pD); }

char operator << (char & u, Address a)

{ return *(a.pointer.PAD); }


// программа копирования содержимого одного адреса в другой

// Гатин Г.Н. 20.04.2004

Address & Address::operator >> (Address & a)

{

int j;

for (j = 0; j < How; ++j)

*(a.pointer.PAD + j) = *(pointer.PAD + j);

a.How = How;

return a;

}

Address & Address::operator << (Address & a)

{

int j;

for (j = 0; j < a.How; ++j)

*(pointer.PAD + j) = *(a.pointer.PAD + j);

How = a.How;

return *this;

}


// программа копирования одной области памяти в другую Гатин Г.Н. 15.04.2004

bool Address::copyMem (Address & a, int I)

{

int j;

if (I < 1) return false;

for (j = 0; j < I; ++j)

*(pointer.PAD + j) = *(a.pointer.PAD + j);

How = I;

return true;

}


template <class T> bool Address::copyMem (T & Obj)

{

int i, j;

Address a;

i = sizeof (Obj);

a.pointer.pVac = &Obj;

for (j = 0; j < i; ++j)

*(pointer.PAD + j) = *(a.pointer.PAD + j);

How = i;

return true;

}


// программа сравнивания одной области памяти с другой Гатин Г.Н. 15.04.2004

int Address::compareMem (Address & a, int I)

{

int j;

if (I < 1) return -2;

for (j = 0; j < I; ++j)

if (*(pointer.PAD + j) != *(a.pointer.PAD + j))

if (*(pointer.PAD + j) < *(a.pointer.PAD + j)) return -1;

else return 1;

return 0;

}

Приложение 6. Текст тестирующей класс Address программы


//-----------------------------------------------------

/* Программа тестирования класса Address. Тип Address - некий НЕТИПИЗИРОВАННЫЙ указатель, который может указывать на переменную любого типа, а при выполнении арифметических действий наращивается именно на 1, а не на размер типа переменной.

Гатин Г.Н. 01.04.2004

*/


#include

#include

#include

#pragma hdrstop


#include "Address.h"

#include "Address.cpp"

#include "AddressTest.h"

//-----------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

union good { // небольшое объединение для демонстрации возможностей типа

double D; // Address

float F;

int I;

};

struct Ks {

good G;

double flash;

} GH;


TTest_Ad *Test_Ad;

//-----------------------------------------------------

__fastcall TTest_Ad::TTest_Ad(TComponent* Owner)

: TForm(Owner)

{

double u;

double z;

float fi;

char * gu;

char buf[512];

AnsiString Buf;

Address Afi = Address(fi);

Address Agt(GH);

Address Au = Address ();

AnsiString pov;

int figa[20];

Aty Agh;

Aty Apop (GH);


MessageDlg (" Размер Address : "+IntToStr(sizeof(Address)),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Au = u;

u = 50;

// MessageDlg (" Адрес u : "+Au,

// mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" длинна типа u : " +IntToStr(Au.LenType()),

mtInformation, TMsgDlgButtons() << mbOK, NULL);


z = Au >> z;

MessageDlg (" Значение z : "+FloatToStr(z),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

u = 70;

MessageDlg (" Значение z : "+FloatToStr(z << Au),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

if (Afi == Au)

MessageDlg (" Адреса равны ",

mtInformation, TMsgDlgButtons() << mbOK, NULL);

else

MessageDlg (" Адреса НЕ равны ",

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Afi = GH.G.F;

Au = GH.flash;

if (Afi < Au)

MessageDlg (" Адрес GH.G.F : "+Afi+

" меньше адреса GH.flash : "+Au,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

else

MessageDlg (" Адрес GH.G.F : "+Afi+

" НЕ меньше адреса GH.flash : "+Au,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" Расстояние между адресами : "+IntToStr(Afi-Au)+" байт. ",

mtInformation, TMsgDlgButtons() << mbOK, NULL);


gu = Au;

MessageDlg (" Размер buf : "+IntToStr(sizeof(buf)),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" Размер figa : "+IntToStr(sizeof(figa)),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

sprintf (buf, " Указатель : %p ", gu);

Buf = buf;

MessageDlg (Buf,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Afi = GH.G.F;

Au = GH.flash;

Au.copyMem(Afi, 2);

gu = new char [100];

MessageDlg (" Размер gu : "+IntToStr(sizeof(gu)),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Au = gu;

Au = z;

z = 150.150;

u = 200;

MessageDlg (" Второй: Значение z:"+FloatToStr(z << Au),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Au.copyMem(u);

MessageDlg (" Третий: Значение z:"+FloatToStr(z << Au),

mtInformation, TMsgDlgButtons() << mbOK, NULL);


Au.copyMem(pov);


pov = " Проба пера на новом поле. ";

Au = buf;

Au.copyMem(pov);

Au = Buf;

MessageDlg (" Распечатка Buf : "+Buf,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

// построение адреса на экзотический тип

Au = Address(GH);

// Au = &GH;

Afi = GH.G;

MessageDlg (" Адрес GH : "+Au,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" Адрес GH : "+Afi,

mtInformation, TMsgDlgButtons() << mbOK, NULL);

if (Afi != Au)

MessageDlg (" Адреса Afi и Au НЕ равны ",

mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" длинна типа GH : " + IntToStr(Au.LenType()),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

Agh = &GH;

MessageDlg (" Размер структуры GH : "+IntToStr(sizeof(GH)),

mtInformation, TMsgDlgButtons() << mbOK, NULL);

MessageDlg (" По Agt : длинна типа GH : " + IntToStr(Agt.LenType()),

mtInformation, TMsgDlgButtons() << mbOK, NULL);


}