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 с параметрами:
Дата добавления: 2018-02-18; просмотров: 496; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!