Методические указания Ухта 2006 удк 681 06(076) г 23
Вид материала | Методические указания |
Приложение 4. Текст заголовка класса Address (файл Address.h) Приложение 5. Тексты членов – функций класса Address (файл Address.cpp) Приложение 6. Текст тестирующей класс Address программы |
- Методические указания Санкт Петербург 2006 удк 947, 435.39kb.
- Методические указания Санкт-Петербург 2011 удк 541. 1(076., 289.58kb.
- Методические указания по выполнению и оформлению курсовой работы по дисциплине «бухгалтерский, 1337.13kb.
- Методические указания Новосибирск 2003 удк ббк т3(2), 342.37kb.
- Методические указания Санкт-Петербург 2009 удк 947, 1006.45kb.
- Удк 340. 6+681. 327+681 015 Д. В. Ландэ, В. Н. Фурашев, 450.24kb.
- Удк 681 053: 681. 32: 007, 134.3kb.
- Администрация, 29.13kb.
- Методические указания Санкт-Петербург 2010 удк 947, 1278.52kb.
- Методические указания для студентов и аспирантов Сыктывкар 2006, 119.19kb.
Приложение 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
Aty
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);
}