- •Овсянник в.Н. Лабораторные работы по курсу «Объектно-ориентированное программирование»
- •1.Интегрированная среда mvs-2010
- •1.1.Методические указания
- •2.Массивушки и подпрограммочки
- •Прочитайте это задание и методические указания до конца, прежде чем терзать клавиатуру, соседа, преподавателя и пр. Сущности
- •Попробуйте сдать работу, предварительно тщательно протестировав ее на предмет отсутствия хомутов
- •2.1.Методические указания
- •3.Поиск экстремумов с ограничениями или «Брачное агенство»
- •Постановка задачи
- •Задание
- •Листинг файла mAgency.Cpp (с главной функцией)
- •Листинг файла Lib.H
- •Листинг файла Lib.Cpp
- •4.Задача «куча камней»
- •4.1.Постановка задачи.
- •4.2.Методические указания.
- •Некоторые примеры разделения камней на две кучи, которые должна решать ваша программа
- •5.Разработка простого класса
- •5.1.Задание
- •5.2.Описание вариантов заданий
- •5.3.Драгоценные методические указания
- •6.Класс вектор
- •6.1.Пример класса tVector
- •6.2.Класс tVector с перегруженными операциями
- •7.Наследование классов
- •7.1.Задание
- •7.2.Методическая помощь
- •7.3.Описание самых легких вариантов заданий
- •7.4.Контроль качества выполненной работы
- •8.Приложение с окном вида
- •9.Абстрактные классы и виртуальные функции
- •9.1.Задание
- •9.2.Методические указания
- •Void PrintClassNamе1(cBasе *pb) // параметр-указатель
- •Void PrintClassNamе2(cBasе &b) // параметр-ссылка
- •Void PrintClassNamе3(cFirst f) // параметр-значение
- •9.3.Варианты заданий
- •10.Разработка класса контейнера
- •10.1.Задание
- •10.2.Описание вариантов заданий
- •10.3.Методические указания
- •12.Перегрузка векторных и матричных операций
- •12.1.Задание
- •12.2.Бесценные методические указания
- •12.3.Некоторые особенности перегрузки операций
- •12.4.Варианты заданий
- •13.Программирование односвязного списка
- •13.1.Задание
- •13.2.Описание вариантов заданий
- •14.Приложение, основанное на модальном диалоговом окне
- •14.1.Нудные методические указания Модальные и немодальные диалоговые окна
- •Ресурсы и элементы управления
- •Сценарий создания приложения
- •Разбор приложения
- •Усовершенствование приложения
- •15.Приложения
- •15.1.Виды сортировок
- •Классификация сортировок
- •Сортировка массивов
- •15.2.Алгоритм сортировки включением
- •Пример сортировки с помощью прямого включения
- •15.3.Сортировка Шелла
- •Список литературы
10.3.Методические указания
В качестве иллюстрации контейнерного класса рассмотрим следующий пример. Пусть имеется класс CDate, который поддерживает обработку дат (день, месяц и год):
// Файл Date.h
#pragma once
class CDate
{
public:
CDate(void);
~CDate(void);
void setDay(int newDay);
void setMonth(int newMonth);
void setYear(int newYear);
int getDay();
int getMonth();
int getYear();
private:
int m_nDay;
int m_nMonth;
int m_nYear;
};
Реализацию этого класса разместим, как принято, в cpp-файле:
// Файл Date.cpp
#include "StdAfx.h"
#include "Date.h"
CDate::CDate(void): m_nDay(0), m_nMonth(0), m_nYear(0)
{
TRACE("Constructor CDate was called\n");
}
CDate::~CDate(void)
{
TRACE("Destructor ~CDate was called\n");
}
void CDate::setDay(int newDay){m_nDay=newDay;}
void CDate::setMonth(int newMonth){m_nMonth=newMonth;}
void CDate::setYear(int newYear){m_nYear=newYear;}
int CDate::getDay(){return m_nDay;}
int CDate::getMonth(){return m_nMonth;}
int CDate::getYear(){return m_nYear;}
Обратите внимание на реализации конструктора и деструктора класса CDate, в которые добавлен макрос TRACE для отслеживания момента их (автоматического) вызова.
Пусть также имеется класс CPerson, назначение которого состоит в обработке данных о служащих. Очевидно, что для каждого служащего надо сохранять несколько дат, например, день рождения, дата поступления на работу, даты отпусков и т.п. Для простоты ограничимся одной датой и опишем класс таким образом:
// Файл Person.h
#pragma once
#include "date.h"
class CPerson
{
public:
CPerson(void);
~CPerson(void);
char * getFName(void);
char * getSName(void);
void setFName(char * newFName);
void setSName(char * newSName);
void setBirthDate(int Day, int Month, int Year);
int getBirthDay();
int getBirthMonth();
int getBirthYear();
private:
char *m_sFName;
char *m_sSName;
CDate m_dBirthDate;
};
=======================================================================
// Файл Person.cpp
#include "StdAfx.h"
#include "Person.h"
CPerson::CPerson(void): m_sFName(NULL), m_sSName(NULL)
{
TRACE("Constructor CPerson was called\n");
}
CPerson::~CPerson(void)
{
if(m_sFName) delete [] m_sFName;
if(m_sSName) delete [] m_sSName;
TRACE("Destructor ~CPerson was called\n");
}
char * CPerson::getFName(void)
{ return m_sFName; }
char * CPerson::getSName(void)
{ return m_sSName; }
void CPerson::setFName(char * newFName)
{
m_sFName=new char [strlen(newFName)+sizeof(char)];
strcpy(m_sFName,newFName);
}
void CPerson::setSName(char * newSName)
{
m_sSName=new char [strlen(newSName)+sizeof(char)];
strcpy(m_sSName,newSName);
}
void CPerson::setBirthDate(int Day, int Month, int Year)
{
m_dBirthDate.setDay(Day);
m_dBirthDate.setMonth(Month);
m_dBirthDate.setYear(Year);
}
int CPerson::getBirthDay()
{ return m_dBirthDate.getDay(); }
int CPerson::getBirthMonth()
{ return m_dBirthDate.getMonth(); }
int CPerson::getBirthYear()
{ return m_dBirthDate.getYear(); }
В приведенном листинге класса CPerson обратите особое внимание на реализацию конструктора и деструктора класса, в которые добавлены макросы TRACE для отслеживания последовательности их вызовов.
Проведем эксперимент: создадим консольное приложение, подключим к нему заголовочный файл Person.h и добавим в главную функцию следующий код:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// ...
CPerson *pPers;
pPers=new CPerson;
delete pPers;
// ...
}
После запуска приложения на выполнение в окне Debug мы увидим следующие строки:
Constructor CDate was called
Constructor CPerson was called
Destructor ~CPerson was called
Destructor ~CDate was called
Этот эксперимент дает ответ на вопрос о том, когда вызываются конструктор и деструктор «внутреннего» объекта, в данном случае объекта класса CDate, по отношению к вызовам конструктора и деструктора «внешнего» объекта – экземпляра класса CPerson.
А если внутренний объект имеет конструктор с параметрами, то где этот конструктор должен быть вызван? Добавим в класс CDate конструктор с параметрами:
// Файл Date.h
#pragma once
class CDate
{
public:
CDate(void);
CDate(int iDay, int iMonth,int iYear);
// ...
};
==========================================================================
// Файл Date.cpp
CDate::CDate(int iDay, int iMonth,int iYear)
{
m_nDay=iDay; m_nMonth=iMonth; m_nYear=iYear;
TRACE("Constructor CDate was called\n");
}
Если при этом не удалить конструктор класса CDate по умолчанию, т.е. без параметров, то приложение будет компилироваться без ошибок, но если конструктор по умолчанию удалить, то возникнет сообщение об ошибке:
error C2512: 'CDate' : no appropriate default constructor available
Перевод: для класса CDate не определен конструктор по умолчанию. Компилятор при этом будет указывать на конструктор класса CPerson. Конструктор внутреннего объекта CDate с параметрами должен быть вызван, например, в следующем контексте:
CPerson::CPerson(void)
: m_sFName(NULL)
, m_sSName(NULL)
, m_dBirthDate(0,0,0)
{
TRACE("Constructor CPerson was called\n");
}
В этом случае программа будет компилироваться без ошибок и конструктор класса CDate с параметрами будет вызван на выполнение точно так же, как и конструктор без параметров. Для того чтобы конструктору класса CDate передать требуемые параметры, определенные пользователем класса CPerson, можно, например, путем создания конструктора класса CPerson с параметрами:
CPerson::CPerson(int iDay, int iMonth, int iYear)
: m_sFName(NULL)
, m_sSName(NULL)
, m_dBirthDate(iDay, iMonth, iYear)
{
TRACE("Constructor CPerson with parameters was called\n");
}
|
11.
