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; Мы поможем в написании вашей работы!

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






Мы поможем в написании ваших работ!