Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Определение методов классов




Помимо открытых членов-функций, осуществляющих чтение и модификацию закрытых членов-переменных, в классах, используемых в программе, определены и другие члены-функции.

В классе книги определены открытые члены-функции, осуществляющие переход при чтении книги к предыдущей и последующей страницам. Кроме того, в этом классе определена закрытая член-функция RenewCtrls(), которая вызывается вышеупомянутыми функциями при переходе к другой странице. Данная функция вызывает глобальные функции RenewTree() и RenewList(), которые обновляют визуальное содержание представлений оглавления и страницы соответственно.

Классы коллекций разделов, глав и страниц (CRazdels, CGlavas и CPages) имеют открытые члены-функции DeleteRazdels(), DeleteGlavas() и DeletePages() соответственно. Данные члены-функции осуществляют освобождение памяти, выделенной под хранение книги, при открытии другой книги или завершении работы программы.

В классе книги перегружены конструктор и деструктор по умолчанию. Конструктор обнуляет номер текущей страницы для того, чтобы при открытии новой книги автоматически отображалась первая страница. Деструктор запускает механизм освобождения памяти.

Упрощение классов при использовании наследования и графическое изображение объектной модели

Объектно-ориентированный подход в программировании имеет одну очень привлекательную черту – возможность повторного использования уже разработанного кода. Во-первых, можно использовать классы, созданные другими разработчиками, не заботясь о деталях реализации методов внутри класса. Примером могут служить сотни классов из библиотеки MFC. Но более существенные преимущества дает повторное использование кода, реализуемое через механизм наследования.

Класс, использующий код другого класса, называется производным или подклассом. Класс, который предоставляет свой код другому классу, называется базовым или суперклассом. Если есть необходимость предоставить методам порожденного класса возможность прямого доступа к члену-переменной базового класса, вместо квалификатора доступа private можно использовать квалификатор protected. Может оказаться, что методы базового класса, унаследованные порожденным классом, не совсем соответствуют специфике последнего и нуждаются в определенной модификации. Для этого потребуется разработать отдельный метод Имя_Класса::Метод(). Это и есть перегрузка методов базового класса. Если желательно, чтобы метод Имя_Класса::Метод() выполнял то же, что и метод базового класса, а затем и еще нечто, то наилучшим способом достичь такого результата будет вызов Имя_Базового_Класса::Метод() внутри Имя_Класса::Метод(). Но при этом нужно использовать полное имя метода базового класса, т.е. именно Имя_Базового_Класса::Метод().

В приложении классы книги, раздела, главы и страницы унаследованы от CObject. Это необходимо для реализации механизма загрузки документа из файла – метод Serialize() в этих классах перегружается также, как и в классе документа:

void CBookDoc::Serialize(CArchive& ar)

{

    m_Book.Serialize(ar);

}

Классы CRazdels, CGlavas и CPages унаследованы от класса CObArray. Поэтому для объектов этих классов можно вызывать все члены-функции, присущие классу массива объектов.

 

Объектная модель книги


Реализация объектной модели на языке программирования C++

 

Реализация класса книги

BookClass. h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Razdels.h"

 

class CBookClass;

extern void RenewTree(CTreeCtrl*,CBookClass*);

extern void RenewList(CListCtrl*,CBookClass*);

 

class CBookClass: public CObject

{

DECLARE_SERIAL(CBookClass)

private:

    CRazdels m_Razdels;

    CPtrArray m_pPages;

    CTreeCtrl* pTreeCtrl;

    CListCtrl* pListCtrl;

    CString m_Name;

    WORD m_ActivePage;

    void RenewCtrls()

    {

              RenewTree(pTreeCtrl,this);

              RenewList(pListCtrl,this);

    }

public:

    CRazdels* GetRazdels()

    {

              return &m_Razdels;

    }

    CPtrArray* GetPages()

    {

              return &m_pPages;

    }

    void SetTreeCtrl(CTreeCtrl* TreeCtrl)

    {

              pTreeCtrl=TreeCtrl; }

    void SetListCtrl(CListCtrl* ListCtrl)

    {

              pListCtrl=ListCtrl;

    }

    CString* GetName()

    {

              return &m_Name;

    }

    WORD GetActivePage()

    {

              return m_ActivePage;

    }

    void SetActivePage(WORD Page)

    {

              m_ActivePage=Page;

              RenewList(pListCtrl,this);

    }

    void SetPreviousActivePage()

    {

              if (m_ActivePage>0)

              {

                       m_ActivePage--;

                       RenewCtrls();

              }

    }

    void SetNextActivePage()

    {

              if (m_ActivePage+1<m_pPages.GetSize())

              {

                       m_ActivePage++;

                       RenewCtrls();

              }

    }

    CBookClass();

    ~CBookClass();

    void Serialize(CArchive&);

};

 

BookClass.cpp:

 

#include "stdafx.h"

#include "BookClass.h"

 

IMPLEMENT_SERIAL(CBookClass,CObject,0)

 

CBookClass::CBookClass()

{

    m_ActivePage=0;

}

 

CBookClass::~CBookClass()

{

    m_Razdels.DeleteRazdels();

}

 

void CBookClass::Serialize(CArchive& ar)

{

    m_Razdels.DeleteRazdels();

    m_pPages.RemoveAll();

    m_ActivePage=0;

    CObject::Serialize(ar);

    if (ar.IsLoading())

    {

              ar>>m_Name;

              WORD Count,Counter;

              ar>>Count;

              for(Counter=0;Counter<Count;Counter++)

              {

                       CRazdel* Razdel=new CRazdel;

                       Razdel->Serialize(ar);

                       m_Razdels.Add(Razdel);

              }

              for(Counter=0;Counter<m_Razdels.GetSize();Counter++)

              {

                       CRazdel* Razdel=(CRazdel*)m_Razdels.GetAt(Counter);

                       for(WORD Counter2=0;Counter2<Razdel->GetGlavas()->GetSize();Counter2++)

                       {

                                 CGlava* Glava=(CGlava*)Razdel->GetGlavas()->GetAt(Counter2);

                                 for(WORD Counter3=0;Counter3<Glava->GetPages()->GetSize();Counter3++)

                                          m_pPages.Add(Glava->GetPages()->GetAt(Counter3));

                       }

              }

 

    }

}

 

Razdels.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Razdel.h"

 

class CRazdels: public CObArray

{

public:

    void DeleteRazdels();

};

 

Razdels.cpp:

 

#include "stdafx.h"

#include "Razdels.h"

 

void CRazdels::DeleteRazdels()

{

    WORD Counter;

    for(Counter=0;Counter<GetSize();Counter++)

    {

              CRazdel* Razdel=(CRazdel*)GetAt(Counter);

              Razdel->GetGlavas()->DeleteGlavas();

              delete Razdel;

    }

    RemoveAll();

}

 

Razdel.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Glavas.h"

 

class CRazdel: public CObject

{

DECLARE_SERIAL(CRazdel)

private:

    CGlavas m_Glavas;

    CString m_Name;

    WORD m_FirstGlava;

    WORD m_LastGlava;

    WORD m_FirstPage;

    WORD m_LastPage;

public:

    CGlavas* GetGlavas()

    {

              return &m_Glavas;

    }

    CString* GetName()

    {

              return &m_Name;

    }

    WORD GetFirstGlava()

    {

              return m_FirstGlava;

    }

    void SetFirstGlava(WORD FirstGlava)

    {

              m_FirstGlava=FirstGlava;

    }

    WORD GetLastGlava()

    {

              return m_LastGlava;

    }

    void SetLastGlava(WORD LastGlava)

    {

              m_LastGlava=LastGlava;

    }

    WORD GetFirstPage()

    {

              return m_FirstPage;

    }

    void SetFirstPage(WORD FirstPage)

    {

              m_FirstPage=FirstPage;

    }

    WORD GetLastPage()

    {

              return m_LastPage;

    }

    void SetLastPage(WORD LastPage)

    {

              m_LastPage=LastPage;

    }

    CRazdel(){};

    void Serialize(CArchive&);

};

 

Razdel.cpp:

 

#include "stdafx.h"

#include "Razdel.h"

 

IMPLEMENT_SERIAL(CRazdel,CObject,0)

 

void CRazdel::Serialize(CArchive& ar)

{

    CObject::Serialize(ar);

    if (ar.IsLoading())

    {

              ar>>m_Name>>m_FirstGlava>>m_LastGlava>>m_FirstPage>>

m_LastPage;

              WORD Count,Counter;

              ar>>Count;

              for(Counter=0;Counter<Count;Counter++)

              {

                       CGlava* Glava=new CGlava;

                       Glava->Serialize(ar);

                       m_Glavas.Add(Glava);

              }

    }

}

 

Glavas.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Glava.h"

 

class CGlavas: public CObArray

{

public:

    void DeleteGlavas();

};

 

Glavas.cpp:

 

#include "stdafx.h"

#include "Glavas.h"

 

void CGlavas::DeleteGlavas()

{

    WORD Counter;

    for(Counter=0;Counter<GetSize();Counter++)

    {

              CGlava* Glava=(CGlava*)GetAt(Counter);

              Glava->GetPages()->DeletePages();

              delete Glava;

    }

    RemoveAll();

}

 

Glava.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Pages.h"

 

class CGlava: public CObject

{

DECLARE_SERIAL(CGlava)

private:

    CPages m_Pages;

    CString m_Name;

    WORD m_FirstPage;

    WORD m_LastPage;

public:

    CPages* GetPages()

    {

              return &m_Pages;

    }

    CString* GetName()

    {

              return &m_Name;

    }

    WORD GetFirstPage()

    {

              return m_FirstPage; }

    void SetFirstPage(WORD FirstPage)

    {

              m_FirstPage=FirstPage;

    }

    WORD GetLastPage()

    {

              return m_LastPage;

    }

    void SetLastPage(WORD LastPage)

    {

              m_LastPage=LastPage;

    }

    CGlava(){};

    void Serialize(CArchive&);

};

 

Glava.cpp:

 

#include "stdafx.h"

#include "Glava.h"

 

IMPLEMENT_SERIAL(CGlava,CObject,0)

 

void CGlava::Serialize(CArchive& ar)

{

    CObject::Serialize(ar);

    if (ar.IsLoading())

    {

              ar>>m_Name>>m_FirstPage>>m_LastPage;

              WORD Count,Counter;

              ar>>Count;

              for(Counter=0;Counter<Count;Counter++)

              {

                       CPage* Page=new CPage;

                       Page->Serialize(ar);

                       m_Pages.Add(Page);

              }

    }

}

 

 

Pages.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Page.h"

 

class CPages: public CObArray

{

public:

    void DeletePages();

};

 

Pages.cpp:

 

#include "stdafx.h"

#include "Pages.h"

 

void CPages::DeletePages()

{

    WORD Counter;

    for(Counter=0;Counter<GetSize();Counter++)

    {

              CPage* Page=(CPage*)GetAt(Counter);

              delete Page;

    }

    RemoveAll();

}

 

Page.h:

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define CountOfStrings 37

 

class CPage: public CObject

{

DECLARE_SERIAL(CPage)

private:

    CString m_Strings[CountOfStrings];

    CString m_Name;

    HTREEITEM m_TreeItem;

public:

    CString* GetString(BYTE Index)

    {

              return &m_Strings[Index];

    }

    CString* GetName()

    {

              return &m_Name;

    }

    HTREEITEM GetTreeItem()

    {

              return m_TreeItem;

    }

    void SetTreeItem(HTREEITEM TreeItem)

    {

              m_TreeItem=TreeItem;

    }

    CPage(){};

    void Serialize(CArchive&);

};

 

Page.cpp:

 

#include "stdafx.h"

#include "Page.h"

 

IMPLEMENT_SERIAL(CPage,CObject,0)

 

void CPage::Serialize(CArchive& ar)

{

    CObject::Serialize(ar);

    if (ar.IsLoading())

    {

              ar>>m_Name;

              BYTE Counter;

              for(Counter=0;Counter<CountOfStrings;Counter++)

                       ar>>m_Strings[Counter];

    }

}

 
Порождение объектов

 

В файле Book.cpp объявляется глобальная переменная – объект класса приложения CBookApp:

CBookApp theApp;

В перегруженной функции-члене InitInstance() класса CBookApp создаются объекты классов документа, окна и представления оглавления:

 

BOOL CBookApp::InitInstance()

{

    CSingleDocTemplate* pDocTemplate;

    pDocTemplate = new CSingleDocTemplate(

              IDR_MAINFRAME,

              RUNTIME_CLASS(CBookDoc),

              RUNTIME_CLASS(CMainFrame),

              RUNTIME_CLASS(CLeftView));

    AddDocTemplate(pDocTemplate);

    return TRUE;

}

 

Класс окна CMainFrame содержит защищенный атрибут класса CSplitterWnd, предоставляющий доступ к представлению страницы посредством вызова открытой член-функции класса CMainFrame:

 

class CMainFrame: public CFrameWnd

{

protected:

    CSplitterWnd m_wndSplitter;

public:

    CBookView* GetRightPane();

};

 

Объект класса книги является открытым атрибутом класса документа:

 

class CBookDoc: public CDocument

{

public:

    CBookClass m_Book;

};

 

Все структурные элементы книги (разделы, главы и страницы) создаются в момент загрузки файла книги с диска через оператор new:

 

CRazdel* Razdel=new CRazdel;

m_Razdels.Add(Razdel);


Вызов операций

 

Вызов операций для объектов в C++ может быть организован двумя способами:

1) Если требуется вызвать операцию для переменной, являющейся объектом какого-либо класса, то используется оператор.*:

Object.MemberFunc();

2) Если переменная является указателем на объект класса, то доступ к методам, поддерживаемым данным классом, организовывается через оператор ->*:

pObject->MemberFunc();

Т.к. объект класса книги является открытым атрибутом класса документа, то доступ к членам класса книги осуществляется через указатель на объект класса документа. Т.о., чтобы вызвать функцию-член класса CBookClass, необходимо получить вначале указатель на объект класса CBookDoc:

 

CBookDoc* pDoc = GetDocument();

pDoc->m_Book.SetTreeCtrl(&refCtrl);

 

Если члены-функции вызываются внутри их класса, то вызов этих функций осуществляется напрямую без указания имени класса. Например, внутри функции CRazdels::DeleteRazdels() осуществляется вызов членов-функций, наследуемых от базового класса CObArray:

 

void CRazdels::DeleteRazdels()

{

    WORD Counter;

    for(Counter=0;Counter< GetSize(); Counter++)

    {

              CRazdel* Razdel=(CRazdel*) GetAt(Counter);

              Razdel->GetGlavas()->DeleteGlavas();

              delete Razdel;

    }

    RemoveAll();

}


Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...