C++: Л/р№6 ООП. Конструктор и деструктор. Перегрузка функций и операторов.
реклама
Объектно-ориентированное программирование (ООП). Применение конструкторов и деструкторов. Перегрузка функций и операторов (2 часа)
Цель работы: изучение правил описания и использования классов и объектов, конструкторов и деструкторов, и использования перегрузки функций и операторов.
Порядок выполнения работы
1.Провести анализ примеров. Программы из примеров копируются в файлы С++ и выполняются.
2.Выполнить задания.
3.Защитить выполненную работу.
Контрольные вопросы
1.Как работают программы примеров?
2.Можно ли перегружать конструктор?
3.Сколько раз можно перегружать оператор?
Теоретические сведения
Среди функций-членов класса имеются такие, которые определяют особенности создания, инициализации, копирования и уничтожения объектов данного класса. Конструкторы и деструкторы – пример наиболее важных специальных функций-членов. Как и обычные функции-члены, конструкторы и деструкторы могут описываться в пределах или вне класса, конструкторы могут быть "перегружены". Однако есть и ряд особенностей этих функций.
Функция-член класса, основная цель которой – инициализация переменных объекта данного класса или распределение памяти для их хранения, называется конструктором. Конструктор имеет такое же имя, как и класс, в котором он определен. С объектом всегда связано либо явное, либо неявное выполнение конструктора. Если отсутствует явно описанный конструктор (нет функции-члена, имя которой совпадает с именем класса), C++ генерирует автоматически так называемый конструктор по умолчанию (Default Constructor). Конструктор не может быть вызван явно из пределов программы. Он вызывается явно компилятором при создании объекта и неявно при выполнении оператора new, применяемого к объекту, а также при копировании объекта данного класса.
Функция-деструктор разрушает объект данного класса и вызывается явно или неявно. Неявный вызов деструктора связан с прекращением существования объекта из-за завершения области его определения. Например, объект является локальным внутри функции и функция возвращает управление. Явное уничтожение объекта выполняет оператор delete. Деструктор имеет такое же имя, как и класс, но предваряется символом ~. В отличие от конструкторов деструкторы не могут получать аргументы и быть "перегружены".
Конструктор, как и любая функция, может иметь любое количество параметров, в том числе и параметров по умолчанию. Конструктор, не имеющий аргументов, называется конструктором по умолчанию. Если отсутствует определенный пользователем конструктор по умолчанию, Borland C++ генерирует собственный конструктор по умолчанию для описанного класса.
Особый тип конструктора – это так называемый конструктор копирования. Конструктор копирования для класса Х -это конструктор, который имеет один ар1умент типа Х и, возможно, параметры по умолчанию.
Язык программирования C++ допускает "перегрузку' операторов (overloading), т. е. придание привычным операторам +, –, * и другим нового смысла. Кроме того, "перегрузка" операторов действует и допускается в пределах контекста класса. Ниже перечислены все операторы и встроенные функциональные вызовы, которые могут быть переопределены:
+ - * / - < > += -= *= /= << >> <<= >>= = =
!= <= >= ++ -- % & ^ ! | ~ &= ^= |= && ||
% [] () new delete
Смысл "перегрузки" в том, что создается функция, вызываемая каждый раз, когда в контексте класса упоминается переопределенный оператор. Синтаксис определения "перегрузки" оператора таков:
имя_типа operator символ_операции(список_параметров),
где поле "имя_типа" задает тип возвращаемого значения при выполнении функции, заменяющей оператор; поле "символ_операции" – символ перегружаемой операции; поле "список_параметров" определяет тип передаваемых параметров при каждом вызове функции, заменяющей оператор.
Перегрузка операторов позволяет упростить арифметические и логические операции со сложными типами данных. Например, арифметическое сложение двух значений времени в виде "часы", "минуты", "секунды" или дат в виде "день", "месяц", "год". В Borland C++ так реализованы арифметические операции над комплексными числами.
Далее приводится пример программы, использующей класс good_time и перегрузку оператора сложения. Время задается как строка символов вида ЧЧ@ММ@СС, где @ - любой из разделителей: запятая, точка, двоеточие или пробел. Если не заданы секунды (СО, минуты (ММ) или часы (ЧЧ), для них принимается нулевое значение.
Пример 1. Пример перегрузки оператора + при вычислении времени в формате часы, минуты, секунды.
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
char * delimiters = ",: .";
class good_time {
int hours, minutes, secs;
public:
good_time() // конструктор без параметров
{ hours = minutes = secs = 0; }
good_time(char *); // конструктор c передачей параметра
good_time operator +(good_time); // определение
// перегрузки оператора сложения
void output(void);
};
good_time::good_time(char * given_time)
{
hours = atoi(strtok(given_time, delimiters));
minutes = atoi(strtok(NULL, delimiters));
secs = atoi(strtok(NULL, delimiters));
}
good_time good_time::operator+(good_time add_object)
{
good_time temp_object;
temp_object.secs = (secs + add_object.secs) % 60;
temp_object.minutes = ((secs + add_object.secs) / 60 +
minutes + add_object.minutes) % 60;
temp_object.hours = ((secs + add_object.secs) /60 +
minutes + add_object.minutes) / 60 +
hours + add_object.hours;
return temp_object;
}
#include <stdio.h>
void good_time::output(void)
{
char target[12];
printf("%4s час ", itoa(hours, target, 10));
printf("%4s мин ", itoa(minutes, target, 10));
printf("%4s ceк\n", itoa(secs, target, 10));
}
void main(void)
{
good_time first_time("0:0:600");
cout << "Если ";
first_time.output();
cout << "сложить с ";
good_time second_time("300 600 0");
second_time.output();
cout << "получится ";
good_time result_time;
result_time = first_time + second_time;
result_time.output();
}
Задание:
Программу, составленную в лабораторной работе 5, дополнить конструктором и деструктором, соответственно инициализирующим поля объекта и сообщающим об удалении объекта, а также описать и применить перегруженный оператор сложения (знак +) позволяющий складывать объекты.
Решение by 4upuk:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
///////////////////////////////////////////ini//////////////
struct time { int den;
long int chas;
long int minuta;
long int sekunda;};
class date{ public:
date()
{};
date (long int a, long int b, long int c)
{Time.chas=a;
Time.minuta=b;
Time.sekunda=c;};
~date(){puts("Trget must die... :X");};
struct time Time;
int perevod(long int);
date operator - (date);
} t_date,result,def(23,59,60);
date date::operator - (date v)
{ date res;
res.Time.chas=Time.chas-v.Time.chas;
res.Time.minuta=Time.minuta-v.Time.minuta;
res.Time.sekunda=Time.sekunda-v.Time.sekunda;
return res;
}
////////////////////////////////////////////////main////////////
void main(void)
{
int Q,sv,c;
long int sek;
char* nedelja[7] = { "Џ®Ґ¤Ґ«мЁЄ","‚в®аЁЄ","‘। ",
"—ҐвўҐаЈ"," ЏпвЁж "," ‘гЎЎ®в ","‚®бЄаҐбҐмҐ"};
clrscr();
printf("Vibirete format vremeni:\n");
printf("V sekundah(press1)\n");
printf("V 4asah, minutah, sekundah(press2)\n");
scanf("%d",&sv);
switch(sv)
{ case 1: printf("vvedite vremja v secundah");
scanf("%li",&(sek));
t_date.perevod(sek);
printf("\nperevedennoe is sekund vremja %lichas(a) %liminut(y) %lisekund(y)",
t_date.Time.chas,t_date.Time.minuta,t_date.Time.sekunda);
printf("\nDen' nedeli %s,\nego nomer %d\n",nedelja[t_date.Time.den],t_date.Time.den+1);
getch();break;
case 2: printf("vvedite den'");
scanf("%d",&t_date.Time.den);
printf("vvedite chas");
scanf("%li",&(t_date.Time.chas));
printf("vvedite min");
scanf("%li",&(t_date.Time.minuta));
printf("vvedite sek");
scanf("%li",&(t_date.Time.sekunda));
printf("\nOmskoe vremja %lichasa(ov) %liminut(i) %lisekund(i) ",
t_date.Time.chas,t_date.Time.minuta,t_date.Time.sekunda);
printf("\nDen' nedeli %s\n",nedelja[t_date.Time.den-1]);
getch(); break;
}
result=def-t_date;
printf("%li, %li, %li do kontsa tekushih sutok",result.Time.chas,result.Time.minuta,result.Time.sekunda);
getch();
}
///////////////////////////////////////fun_perevoda//////////////
int date::perevod(long int sek)
{
Time.den=sek/86400;
Time.chas=sek/3600-Time.den*24;
Time.minuta=(sek-(Time.den-1)*86400)%3600/60;
Time.sekunda=(sek-(Time.den-1)*86400)%3600%60;
return(0);
}
///////////////////////////the_end/////////////////////////////////////
Решение by Алексей Борисенко:
#include<stdio.h>
#include<conio.h>
#include<time.h>
enum WEEK { pon=1,
vtor,
sred,
chetv,
pjatn,
subb,
voskr};
struct TIME{
int hours;
int min;
int sec;};
class DATE{ public:
DATE()
{};
~DATE(){printf("target destroyed");}
enum WEEK data;
struct TIME m_time;
int perevod(unsigned int);
void vvod(struct DATE* ptr);
void timer(void);
} m_date,*ptr;
int d_dat;
void main()
{
clrscr();
// struct DATE
int index,d_kon,t_tim,a,b,c,ipon,f;
unsigned int res;
ptr=&m_date;
char *d_ned[7]={"ponedelnik","vtornik","sreda","chetverg","pjatnitsa",
"subbota","voskresen'e"};
printf("vvedite den' nedeli ");
scanf("%d", &d_dat);
printf("vvedite vremja:v sekundah(press1)\n"
"v formate hours, min, sec(press2)\n"
"mozhno vospolzovatsja sistemnim timerom(press3)");
scanf("%d",&index);
switch(index)
{
case 1: printf("vvodite ");scanf("%u",&res);m_date.perevod(res); break;
case 2: ptr=&m_date; m_date.vvod( ptr ); break;
case 3: m_date.timer(); break;
default: return;
}
ipon=m_date.data=pon;
f=m_date.data=voskr;
d_kon=f-d_dat;
t_tim=d_kon*24;
a=t_tim+(23-m_date.m_time.hours);
b=59-m_date.m_time.min;
c=60-m_date.m_time.sec;
printf("\nPonedelnik %d den nedeli.\nSejchas %d den nedeli. Tochnee %s\n"
"Do kontsa nedeli %d dnej(dnja).\nTochnee %d chasov %d min %d sec",
ipon, d_dat,d_ned[d_dat-1],d_kon,a,b,c);
delete ptr;
getch();
}
int DATE::perevod(unsigned int sec)
{
unsigned int ch,m,s;
// printf("vvedite vremja v sekundah ");
// scanf("%u",&sec);
printf("%u\n",sec);
ch=sec/3600;
m=(sec%3600)/60;
s=(sec%3600)%60;
printf("%u chasov %umin, %usec",ch,m,s);
m_date.m_time.hours=ch;
m_date.m_time.min=m;
m_date.m_time.sec=s;
return 0;
}
void DATE::vvod(struct DATE* ptr)
{ printf("vvedite vremja: hours, min, sec ");
scanf ("%d,%d,%d",&ptr->m_time.hours,&ptr->m_time.min,&ptr->m_time.sec);
//printf ("%d,%d,%d",ptr->m_time.hours,ptr->m_time.min,ptr->m_time.sec);
}
void DATE::timer(void)
{time_t ltime;
time(<ime);
tm *ptr;
ptr=localtime(<ime);
m_date.m_time.hours=ptr->tm_hour;
m_date.m_time.min=ptr->tm_min;
m_date.m_time.sec=ptr->tm_sec;
d_dat=ptr->tm_wday;
printf("sys timer %d:%d:%d",m_date.m_time.hours,m_date.m_time.min,m_date.m_time.sec);
}
По материалам ОмГУПС, все права защищены... :P
реклама
Лента материалов
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.
Сейчас обсуждают