Лабораторно упражнение No 4 Работа с класове и обекти в С++



Дата27.08.2016
Размер127.13 Kb.
Лабораторно упражнение No 4

Работа с класове и обекти в С++

Цел: Целта на настоящото упражнение е да запознае студентите със създаването и използването на класовете и обектите в С++. Ще бъдат разгледани някои от познатите от предходните упражнения алгоритми, вече написани на С++. В края са показани задачи за самостоятелна работа, които ще помогнат за подготовката за контролните работи.
Задачи за изпълнение:

1. Разгледайте готовият пример EXAM11.CPP. Изпълнете го и отговорете на въпроса: Какво е условието на задачата?

Решение:

Ето я готовата програма. (За вас оставяме да я пуснете в средата на VC++):

#include

#include

class timeobj {

friend ostream & operator << (ostream &, tm ) ;

time_t tt;

tm *t;


public:

timeobj () { time(&tt); t = localtime(&tt); cout<<*t; }

};
ostream & operator << (ostream & cout, tm t)

{ cout << (unsigned) t.tm_hour << ':' << (unsigned) t.tm_min << '*'



<< (unsigned) t.tm_sec << '\n';

return cout;}


void main(void)

{ timeobj t;

}

Ето примерен екран след компилация на програмата:



Нека разгледаме подробно решението: в лявата половина се вижда класа, дефиниран в програмата: timeobj. Той има е конструктор, който е общодостъпен и две скрити член-променливи: tt и t. Ето информация за тях и функциите, които ги ползват от MSDN:


time


Get the system time.

time_t time(

time_t *timer

);

__time64_t _time64(

__time64_t *timer

);

Parameters


timer

Pointer to the storage location for time.


Return Value


Return the time in elapsed seconds. There is no error return.

A call to time can fail, however, if the date passed to the function is:



  • Before midnight, January 1, 1970.

  • After 19:14:07, January 18, 2038, UTC (using time and time_t).

Remarks


The time function returns the number of seconds elapsed since midnight (00:00:00), January 1, 1970, coordinated universal time (UTC), according to the system clock. The return value is stored in the location given by timer. This parameter may be NULL, in which case the return value is not stored.

localtime


Convert a time value and correct for the local time zone.

struct tm *localtime(

const time_t *timer

);

struct tm *_localtime64(

const __time64_t *timer

);

Parameter


timer

Pointer to stored time.


Return Value


Return a pointer to the structure result. If the value in timer represents a date before midnight, January 1, 1970, return NULL.

localtime represents dates through 19:14:07 January 18, 2038, UTC.

The fields of the structure type tm store the following values, each of which is an int:



tm_sec

Seconds after minute (0 – 59).



tm_min

Minutes after hour (0 – 59).



tm_hour

Hours after midnight (0 – 23).



tm_mday

Day of month (1 – 31).



tm_mon

Month (0 – 11; January = 0).



tm_year

Year (current year minus 1900).



tm_wday

Day of week (0 – 6; Sunday = 0).



tm_yday

Day of year (0 – 365; January 1 = 0).



tm_isdst

Positive value if daylight saving time is in effect; 0 if daylight saving time is not in effect; negative value if status of daylight saving time is unknown. If the TZ environment variable is set, the C run-time library assumes rules appropriate to the United States for implementing the calculation of daylight-saving time (DST).


Remarks


The localtime function converts a time stored as a time_t value and stores the result in a structure of type tm. The long value timer represents the seconds elapsed since midnight (00:00:00), January 1, 1970, UTC. This value is usually obtained from the time function.

gmtime, mktime, and localtime all use a single statically allocated tm structure for the conversion. Each call to one of these routines destroys the result of the previous call.

localtime corrects for the local time zone if the user first sets the global environment variable TZ. When TZ is set, three other environment variables (_timezone, _daylight, and _tzname) are automatically set as well. If the TZ variable is not set, localtime attempts to use the time zone information specified in the Date/Time application in Control Panel. If this information cannot be obtained, PST8PDT, which signifies the Pacific time zone, is used by default. See _tzset for a description of these variables. TZ is a Microsoft extension and not part of the ANSI standard definition of localtime.

Note   The target environment should try to determine whether daylight saving time is in effect.

© 2001 Microsoft Corporation. All rights reserved.

Следователно целта на конструктора е да вземе текущото време и да го разпечати на екрана. Тъй като всички потокови операции работят само със стандартни данни и допускат предефиниране за собствени обекти, ще предефинираме <<. За тази цел се използва глобална приятелска функция. Спомнете си кога трябва да се използва глобална функция и кога може да се предефинира операция с метод на класа?

Условието на задачата е: “Да се разпечати текущото време като се използва собствен клас и предефиниране на операцията за печат на екрана.”


2. Да се реализират операциите с линеен едносвързан списък с помощта на класове.

Решение:

Тук ще покажем едно възможно решение, което използва два класа. Първият клас съдържа информация за отделните елементи на списъка (IntItem), а вторият – се грижи за целия списък и операциите върху него (IntList). При това е налице взаимна зависимост между двата класа, поради което се използва предварителна декларация на единия от тях. За да има достъп IntList до скритите данни на IntItem, IntList се декларира като приятел на IntItem.

#include

class IntList;

class IntItem {

friend class IntList;

private:

IntItem(int v=0) { val=v; next=0; }

IntItem *next;

int val;


};

class IntList {

public:

IntList (int val) { list=new IntItem(val); }



IntList () { list=0; }

~IntList();

insert (int val=0);

append (int val=0);

display (void);

private:


IntItem *list;

IntItem *atEnd();

};

IntList::insert(int val)



{ IntItem *pt=new IntItem(val);

pt->next=list;

list=pt;

return val;

}

IntList::~IntList()



{ IntItem *prv,*pt;

for (pt=list;pt;pt=prv)

{

prv=pt->next;



delete pt;

pt = prv;

}

}

IntItem * IntList::atEnd()



{ IntItem *prv,*pt;

for (prv=pt=list;pt;prv=pt,pt=pt->next) ;

return prv;

}

IntList::append(int val)



{ IntItem *pt=new IntItem(val);

if (list==0)

list=pt;

else


(atEnd())->next=pt;

return val;

}

const int lineLength=16;



IntList::display()

{ if (list==0)

{ cout<<"(Empty)\n";

return 0;

}

cout<<'(';



int cnt=0;

IntItem *pt=list;

while(pt)

{ if (++cnt%lineLength==1 && cnt!=1)

cout<<'\n';

cout<
val<<' ';

pt=pt->next;

}

cout<<")\n";



return cnt;

}
const SZ=12;


void main(void)

{ IntList il;

il.display();

for (int i=0;i

il.display();
IntList il2;

for (i=0;i

il2.display();

}

Създадени са методи за добавяне в началото (IntList::insert) и края (IntList::append) на списъка, както и за печат на списъка на екрана (IntList::display). IntList::аtЕnd връща указател към края на списъка.


Пуснете програмата Exam2.cpp в средата на VC++ и я тествайте как работи. Използвайте дебъгер за тази цел.

Добавете изтриване на един елемент от списъка, както и изтриване на всички елементи с определена стойност.
3. Даден е едномерен масив от 1000 елемента, цели числа. Да се сортира в низходящ ред.

Решение:

Тук ще покажем едно възможно решение, което вградената функция qsort. Ето повече информация за нея от MSDN:


qsort

Requirements


Routine

Required header

Compatibility

qsort

and

ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP

Performs a quick sort.

void qsort(

void *base,

size_t num,

size_t width,

int (__cdecl *compare )(const void *, const void *)

);

Parameters


base

Start of target array.



num

Array size in elements.



width

Element size in bytes.



compare

Comparison function. The first parameter is a pointer to the key for the search and the second parameter is a pointer to the array element to be compared with the key.


Remarks


The qsort function implements a quick-sort algorithm to sort an array of num elements, each of width bytes. The argument base is a pointer to the base of the array to be sorted. qsort overwrites this array with the sorted elements. The argument compare is a pointer to a user-supplied routine that compares two array elements and returns a value specifying their relationship. qsort calls the compare routine one or more times during the sort, passing pointers to two array elements on each call:

compare( (void *) elem1, (void *) elem2 );

The routine must compare the elements, then return one of the following values:



Return value

Description

< 0

elem1 less than elem2

0

elem1 equivalent to elem2

> 0

elem1 greater than elem2

The array is sorted in increasing order, as defined by the comparison function. To sort an array in decreasing order, reverse the sense of "greater than" and "less than" in the comparison function.

© 2001 Microsoft Corporation. All rights reserved.

От написаното по-горе следва, че трябва да създадем глобална функция за сравнение на два елемента. Освен това трябва да отчетем факта, че qsort ще работи бавно при голям брой елементи, поради извикването на функцията за сравнение всеки път. Ето решението:

#include

#include
#define N 10

/*-------------------------------- declaration ---------------------------- */

class MyArray

{

private:



int Arr[N];

public:


void input();

void sort();

void output();

};

int compare( const void *arg1, const void *arg2 );



/*-------------------------------- realization ---------------------------- */

void MyArray::input()

{

cout<<"Input the array:\n";



for (int i=0;i

{

cout<<"A["<

cin>>Arr[i];

}

}


void MyArray::sort()

{

qsort( (void *)Arr, (size_t)N, sizeof( int ), compare );



}
void MyArray::output()

{

cout<<"The result\n";



for (int i=0;i

cout<

}
int compare( const void *arg1, const void *arg2 )

{

return (*( int * ) arg2 - * ( int * ) arg1) ;



}
void main()

{

MyArray m;


m.input();

m.sort();

m.output();

}
Пуснете програмата в средата на VC++ и я тествайте как работи. Изяснете си използването на qsort.



Задачи за самостоятелна работа:

  1. Разгледайте Exam3.cpp. Пуснете програмата в средата на VC++. Обяснете си обектният модел на прозореца, който е реализиран в примера. Какво е предназначението на връщана стойност псевдоним към класа, използван в повечето методи? Как се реализира?

  2. Създаите клас за работа с низове и предефинирайте операциите <<, >>, ==, !, +, += и = за него. Сравнете решението си с Exam4.cpp. Използвахте ли копи-конструктор и защо?

  3. Разгледайте Exam5.cpp. Обяснете си наследяването и виртуалните методи. Какво ще се разпечати на екрана? Пуснете програмата и проверете правилността на отговорите си.

  4. Решете всички разглеждани досега примери чрез класове.

Приложение

Exam3.cpp

#include

#include

#include

#include

const char BELL='\007';

class Screen {

short height,width;

char *cursor,*screen;

Screen & home() { move(0,0); return *this; }

void checkRange(int,int);

row();


remSpace();

public:


Screen & move(int,int);

Screen & reSize(int,int,char='#');

Screen & lineX(int,int,int,char);

Screen & display();

Screen & down();

Screen & forward();

Screen & set(char *);

Screen & set(char);

isEqual(Screen &);

void copy(Screen &);

Screen (int=8,int=40,char='#');

~Screen();

};

void lineY(Screen & s,int row,int col,int len,char ch)



{ s.move(row,col);

for(int i=0;i

}

void Screen::checkRange(int row,int col)



{ if (row<1 || row>height || col<1 || col>width)

{ cerr<<"Coordinate ("<

exit(1);

}

}



inline Screen::row()

{ int pos = cursor-screen+1;

return ((pos+width-1)%width)+1;

}

inline Screen::remSpace()



{ int sz = width*height;

return (screen+sz-cursor-1);

}

Screen & Screen::move(int r,int c)



{ checkRange(r,c);

int row = (r-1)*width;

cursor = screen+row+c-1;

return *this;

}

Screen & Screen::reSize(int h,int w,char bk)



{ Screen *ps = new Screen(h,w,bk);

char *pNew = ps->screen;

char *pOld = screen;

while (*pOld && *pNew) *pNew++ = *pOld++;

this->Screen::~Screen();

*this = *ps;

return *this;

}

Screen & Screen::lineX(int row,int col,int len,char ch)



{ move(row,col);

for(int i=0;i

return *this;

}

Screen & Screen::display()



{ char *p;

for(int i=0;i

{ cout<<'\n';

int offset = width*i;

for(int j=0;j

{ p=screen+offset+j;

cout.put(*p);

}

}



return *this;

}

Screen & Screen::down()



{ if(row()>height) cout.put(BELL);

else cursor += width;

return *this;

}

Screen & Screen::forward()



{ ++cursor;

if(*cursor=='\0') home();

return *this;

}

Screen & Screen::set(char *s)



{ int space=remSpace();

int len=strlen(s);

if (space

{ cerr<<"String will be truncated from position "<

". New string length will be "<

len=space;

}

for (int i=0;i

return *this;

}

Screen & Screen::set(char ch)



{ if(ch=='\0')

cerr<<"Symbol NULL is ignored.\n";

else *cursor=ch;

return *this;

}

Screen::isEqual(Screen & s)



{ if(width!=s.width || height!=s.height) return 0;

char *p=screen,*q=s.screen;

if(p==q) return 1;

while(*p && *q && *p++==*q++) ;

if(*p || *q) return 0;

return 1;

}

void Screen::copy(Screen & s)



{ delete screen;

height=s.height;

width=s.width;

screen=cursor=new char[height*width+1];

if(screen==NULL)

{ cerr<<"Out of memory.\n";

this->Screen::~Screen();

exit(1);


}

strcpy(screen,s.screen);

}

Screen::Screen(int high,int widt,char bkgr)



{ int sz=high*widt;

height=high;

width=widt;

cursor=screen=new char[sz+1];

if(screen==NULL)

{ cerr<<"Out of memory.\n";

this->Screen::~Screen();

exit(1);


}

char *ptr=screen,*endptr=screen+sz;

while(ptr!=endptr) *ptr++=bkgr;

*ptr='\0';

}

Screen::~Screen()



{ delete screen;

}
void main(void)

{ Screen X(3,3),Y(3,3);

// clrscr();

cout<<"Objects are equal "<

Y.reSize(6,6);

cout<<"Objects are not equal "<

lineY(Y,1,1,6,'*'); lineY(Y,1,6,6,'*');

Y.lineX(1,2,4,'*').lineX(6,2,4,'*').move(3,3);

Y.set("hi").lineX(4,3,2,'^').display();

X.reSize(6,6);

cout<<"\n\nObjects are not equal "<

X.copy(Y);

cout<<"Objects are equal "<

cin.get();

}
Exam4.cpp

#include

#include


const SIZE=100;

class String {

friend ostream& operator << (ostream&,String);

friend istream& operator >> (istream&,String&);

friend String operator + (String,String);

public:


String(void) {len=0;};

String(int);

String(char *);

String(String&);

~String(void);

int operator ! (void);

int operator == (String);

String& operator += (String);

String& operator = (String);

String& operator = (char *);

private:

char *str;

int len;

};
String::String(int ln)

{

len=ln;


str=new char [len+1];

str[0]='\0';

}
String::String(char *s)

{

len=strlen(s);



str=new char[len+1];

strcpy(str,s);

}
String::String(String &st)

{

len=st.len;



str=new char[len+1];

strcpy(str,st.str);

}
String::~String(void)

{ if (len)

delete str; }
int String::operator ! (void)

{ return (len==0); }


int String::operator == (String st)

{ return (strcmp(str,st.str)==0); }


String& String::operator += (String st)

{

char *s = new char[len+1];



strcpy(s,str);

len+=st.len;

String::~String();

str=new char[len+1];

strcpy(str,s);

strcat(str,st.str);

return *this;

}
String& String::operator = (String st)

{

String::~String();



len=st.len;

str=new char[len+1];

strcpy(str,st.str);

return *this;

}
String& String::operator = (char *s)

{

String::~String();



len=strlen(s);

str=new char[len+1];

strcpy(str,s);

return *this;

}

String operator + (String st1,String st2)



{

String s=st1;

s += st2;

return s;

}
ostream& operator << (ostream &os,String st)

{ return (os<
istream& operator >> (istream &is,String &st)

{

char inBuf[SIZE];



is>>inBuf;

st=inBuf;

return is;

}
void main(void)

{

String s1,s2,s3;



cin>>s1>>s2;

cout<

s3 = s1+s2;

cout<

s3 = s1;

s3 += s2;

cout<

}
Exam5.cpp

#include

#include

enum ZooLocs{ZOOANIMAL,BEAR,PANDA};

static char *locTable[]={

"Whole zoo area",

"North B1: brown area",

"East B1,P area" };

class ZooAnimal {

friend void print(ZooAnimal *);

public:


ZooAnimal(char *s="ZooAnimal");

virtual ~ZooAnimal() { delete name; }

void link(ZooAnimal *);

virtual void print();

virtual void isA();

protected:

char *name;

ZooAnimal *next;

};

class Bear:public ZooAnimal {



public:

Bear(char *s="Bear",ZooLocs loc=BEAR,char *sci="Ursidae");

~Bear() { delete sciName; }

void print();

void isA();

protected:

char *sciName;

ZooLocs ZooArea;

};

class Panda:public Bear {



public:

Panda(char *,int,char *s="Panda",char *sci="Ailuropoda Melaoleuca",

ZooLocs loc=PANDA);

~Panda() { delete indName; }

void print();

void isA();

protected:

char *indName;

int cell;

};

ZooAnimal::ZooAnimal(char *s):next(0) {



name=new char[strlen(s)+1];

strcpy(name,s);

}

void ZooAnimal::link(ZooAnimal *za)



{ za->next=next;

next=za;


}

void ZooAnimal::isA()

{ cout<<"Animal name: "<

}

void ZooAnimal::print()



{ isA();

}

Bear::Bear(char *s,ZooLocs loc,char *sci):ZooAnimal(s),ZooArea(loc)



{ sciName=new char[strlen(sci)+1];

strcpy(sciName,sci);

}

void Bear::isA()



{ ZooAnimal::isA();

cout<<"\tSname: \t"<

}

void Bear::print()



{ ZooAnimal::print();

cout<<"\tAdress: \t"<

}

Panda::Panda(char *nm,int room,char *s,char *sci,ZooLocs loc):



Bear(s,loc,sci),cell(room) {

indName=new char[strlen(nm)+1];

strcpy(indName,nm);

};

void Panda::isA()



{ Bear::isA();

cout<<"\tCall our friend: \t"<

}

void Panda::print()



{ Bear::print();

cout<<"\tCell No: \t"<

}

void print(ZooAnimal *pz)



{ while(pz)

{ pz->print();

cout<<'\n';

pz=pz->next;

}

}
ZooAnimal *headPtr=0,circus("Circus animal");



Bear yogi("Little bear",BEAR,"ursus cartoonus");

Panda yinYang("Yin Yang",1001,"Big Panda"),

rocky("Rocky",943,"Red Panda","Ailurus fulgena");
ZooAnimal * makelist(ZooAnimal *ptr)

{ ptr=&yinYang;

ptr->link(&circus);

ptr->link(&yogi);

ptr->link(&rocky);

return ptr;

}
void main()

{ cout<<"Virtual Function Example\n";

headPtr=makelist(headPtr);

print(headPtr);



}

Лабораторно упражнение No 4

Каталог: KST all -> Semesters -> semestar%205 -> PE misho
Semesters -> Спектрален анализ на сигналите
Semesters -> Билет N1: Степен на интеграцяи. Поколения ис
Semesters -> Проектиране и имплементация върху електрически конфигурируеми (програмируеми) fpga чипове на системи с програмно управление
Semesters -> Видове памети с непосредствен достъп. Структура. Параметри. Особености
PE misho -> В паметта за съхраняване на таблицата се използва структура сортиран списък
semestar%205 -> Конспект по „Операционни Системи Учебна 2010/2011 I. Компютърна система и ос общ преглед Основни Елементи на кс. Регистри. Видове и функционалност Прекъсвания
semestar%205 -> Е логическа нула се отварят изходните буфери. Сигналите
PE misho -> Програма на с #include #include #include int m[10]={0x3938,0x3538,0x3931,0x3333,0x3137,0x3435,0x3839,0x3337,0x3835,0x3532}; int v[10]


Поделитесь с Вашими друзьями:


База данных защищена авторским правом ©obuch.info 2019
отнасят до администрацията

    Начална страница