Добавить в цитаты Настройки чтения

Страница 173 из 372

      pJournal —> nYear = nY;

      cout << "Number: "; cin >> nN;

      pJournal —> nNumber = nN;

      aPub[nNewID].nPubldx = 2;

      aPub[nNewID++].pPub = pJournal;

}

Данный код содержит ряд недостатков, которые (хотя бы отчасти) можно объяснить стремлением придерживаться процедурного подхода

• Наличие нескольких глобальных функций и связанных с ними глобальных данных

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

• Хранение в массиве aPub не только указателя на издание (void* pPub), но и информации о типе издания (int nPubldx)

Информация о типе необходима для выполнения явного преобразования типа

pBook = (Book*) aPub[id].pPub,

pJournal = (Journal*) aPub[id].pPub,

которое необходимо использовать и при выводе описаний изданий и при освобождении динамически выделенной памяти.

Объектно-ориентированное программирование

Теперь рассмотрим объектную реализацию предыдущей программы. Проект включает в три класса: базовый класс CPubiication и производные от него классы CBоок и CJournal, главной функции в файле publications.срр реализуется основная бизнес-логика.

// Заголовочный файл CPublication.h для класса CPublication

#ifndef _CPUBLICATION_

#define _CPUBLICATION_

#define MAX LENGTH 100 // максимальное число символов в имени автора и названии публикации

// Базовый класс

class CPublication

{

public:

     CPublication (); // конструктор

     virtual ~CPublication(); // деструктор

     virtual void Display (); // вывод описания публикации

protected:

     char m_szTitle[MAX_LENGTH]; //название публикации

     int m_nYear; // год издания

};

#endif

Следующий файл содержит реализацию класса CPublication

// Файл CPublication.срр — реализация класса CPublication

#include "CPublication.h"

#include <iostream.h>

// Конструктор

CPublication::CPublication()

{

// Ввод года издания и названия

     cout << "Year: ";

     cin >> m_nYear;

     cout << "Title;";

     cin >> m_szTitle;

}

// Деструктор

CPublication::~CPublication ()

{

}

// Вывод описания публикации

void CPublication::Display()

{

     cout << "PUBLICATION: " << endl;

     cout << "Title: "<< m_szTitle << endl;

     cout << "Year: "<< m_nYear «endl;

}

Файлы CBook.h и CBook.cpp задают класс CBook.

// СВоок.h

#ifndef _СВООК_

#define _СВООК_

#include "CPublication.h"

class CBook: public CPublication // класс CBook — производный от CPublication

{

public:

     CBook(); // конструктор

     virtual ~CBook(); //деструктор

     virtual void Display(); // вывод описания книги

protected;

char m_szAuthor [MAX_LENGTH]; //имя автора

};

#endif

// CBook.cpp

#include <iostream.h>

#include "CBook.h"

// Конструктор

CBook::CPublication()

{

// Ввод имени автора

     cout <<"Author: ";

     cin >> m_szAuthor;

}

// Деструктор

CBook::~CBook()





{

}

// Вывод описания книги

void CBook::Display ()

{

     cout << "BOOK: " << endl;

     cout << "Author: " << m_szAuthor << endl;

     cout << "Title: " << m_szTitle << endl;

     cout << "Year: " << m_nYear<< endl;

}

Файлы CJournal.h и СJournal.cpp задают класс СJournal.

// СJournal.h

#ifndef _CJOURNAL_

#define _CJOURNAL_

#include "CPublication.h"

class СJournal: public CPublication // класс СJournal — производный от CPublication

{

public:

     СJournal(); // конструктор

     virtual ~СJournal(); //деструктор

     virtual void Display(); // вывод описания книги

protected;

     int m_Number; // номер журнала

};

#endif

// СJournal.cpp

#include <iostream.h>

#include "CJournal.h"

// Конструктор

CJournal::CJournal(): CPublication ()

{

// Ввод номера журнала

     cout << "Number: ";

     cin >> m_nNumber;

}

// Деструктор

CJournal::~CJournal ()

{

}

// Вывод описания журнала

void СJournal::Display()

{

     cout << "Journal: " << endl;

     cout << "Title: " << m_nTitle << endl;

     cout << "Year: " << m_nYear << endl;

     cout << "Number: " << m_nNumber << endl;

}

И, наконец, файл publications.cpp с бизнес-логикой

// Книги и журналы (объектно-ориентированное программирование)

#include <iostream.h>

#include "CBook.h"

#include "CJournal.h"

#define MAX_ID 100 // максимальное число изданий

void main()

{

     int nMenu, flag = 1;

     int nNewID =0; // индекс нового издания

     CPublication* aCPublication[MAX_ID]; // массив изданий

     while(nNewID < MAX_ID && flag)

     {

// Вывод пунктов меню

           cout << "Новое издание. Введите: "<< endl;

           cout << " 1 для книги,n 2 для журналаn 3 — выход" << endl;

// Выбор пункта меню

            cin >> nMenu;

            switch (nMenu)

            { case 1: aCPublication[nNewID++] = new CBook(); break;

              case 2: aCPublication[nNewID++] = new CJournal(); break;

              default: flag = 0; break;

            }

      }

// Вывод описаний изданий

    for (int id = 0; id < nNewID; id++)

    {

        aCPublication[id]->Display();

        delete aCPublication[id];

     }

}

В данном примере демонстрируется использование основных принципов объектно-ориентированного программирования

• Инкапсуляция

Инкапсуляция означает сокрытие от пользователя класса его внутренней кухни. Данные и функции (методы) хранятся вместе, доступ к данным (которые следует размещать в защищенной секции protected или private) доступен только с помощью методов класса. Это позволяет разработчику класса менять код класса не изменяя код использующих его приложений (если только не были изменены сигнатуры методов).