chitay-knigi.com » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 197 198 199 200 201 202 203 204 205 ... 361
Перейти на страницу:
IUnknown

STDMETHODIMP_(ULONG) CoBook::AddRef()

{

               return ++m_refCount;

}

STDMETHODIMP_(ULONG) CoBook::Release()

{

              if (--m_refCount == 0)

              {

                          delete this;

                          return 0;

               }

               else

                          return m_refCount;

}

STDMETHODIMP CoBook::Querylnterface(REFIID riid, void** pIFace)

{

                if (riid == IID_IUnknown)

                {

                            *pIFace = (IUnknown*)this;

                }

                else if (riid == IID_IPub)

                }

                            *pIFace = (IPub*)this;

                 }

                else if (riid == IID_IBook)

                 {

                            *pIFace = (IBook*)this;

                 }

                 else

                 {

                            *pIFace = NULL; return E_NOINTERFACE;

                 }

                 ((IUnknown*)(*pIFace))->AddRef();

                 return S OK;

}

//IPub&IBook

                 STDMETHODIMP CoBook::SetTitle (BSTR bstrTitle)

                 {

                            SysReAllocString(&m_bstrTitle, bstrTitle);

                            return S_OK;

                  }

                  STDMETHODIMP CoBook::SetYear(int nYear)

                  {

                           m_nYear = nYear;

                           return S_OK;

                  }

                  STDMETHODIMP CoBook::SetAuthor(BSTR bstrAuthor)

                  {

                           SysReAllocString(&m_bstrAuthor, bstrAuthor);

                           return S_OK;

                   }

                   STDMETHODIMP CoBook::Getlnfo(BSTR *pbstrInfo)

                   {

                         char* pszTitle = NULL;

                         char* pszAuthor = NULL;

                         char* pszText = NULL;

                         int nAuthorLength, nTitleLength;

                         nAuthorLength = SysStringLen(m_bstrAuthor);

                         nTitleLength = SysStringLen(m_bstrTitle);

                         pszAuthor = (char*)malloc(2*nAuthorLength);

                         pszTitle = (char*)malloc(2*nTitleLength);

                         pszText = (char*)malloc(2*nAuthorLength + 2*nTitleLength + 50);

                         wcstombs(pszTitle, m_bstrTitle, 2*nTitleLength);

                         wcstombs(pszAuthor, m_bstrAuthor, 2*nAuthorLength);

                         sprintf(pszText,

                              "BooknnAuthor: %snTitle: %snYear: %d", pszAuthor, pszTitle, m_nYear);

                                  *pbstrInfo = SysAllocStringLen(NULL, 2*strlen(pszText));

                          mbstowcs (*pbstrInfo, pszText, 2*strlen (pszText));

                          free(pszAuthor);

                          free(pszTitle);

                          free(pszText);

                          return S_OK;

          }

В конструкторе CoBook () задается начальное нулевое значение для счетчика числа ссылок на данный объект и увеличивается на 1 глобальный счетчик объектов. Глобальный счетчик объектов используется при принятии решения о возможности удаления из памяти сервера, возможно содержащего не только класс CоBоок, но и какие-то другие классы. Кроме того, члены класса m_bstrTitie и m_bstrAuthor получают в качестве значения пустую строку. Префикс L перед строкой константой говорит о том, что в этой строке на один символ отводится два байта. Для ее преобразования к типу BSTR и размещения в памяти используется функция SysAllocString ().

В деструкторе CоBооk () при уничтожении объекта на 1 уменьшается счетчик объектов и освобождается память, выделенная ранее для заголовка публикации и имени автора. Для освобождения памяти, выделенной под BSTR-строку, используется функция SysFreeString ().

Реализация методов AddRef () и Release () тривиальна и полность соответствует предписанной семантике этих методов.

Метод Query inter face () обеспечивает переход между любыми двумя интерфейсами, реализованными в коклассе совоок. Заметим, что среди этих интерфейсов не только IBook, но и все интерфейсы, от которых прямо или косвенно IBook порожден — IPub и IUnknown. Если запрашиваемый интерфейс не найден, возвращается E_NOINTERFACE. В противном случае вызывается метод AddRef () интерфейса IUnknown, увеличивающий счетчик ссылок на данный объект. Вызвать функцию Release () при освобождении ссылки, полученной в результате вызова QueryInterface () обязан уже клиент.

Методы SetTitle (), SetYear () и SetAuthor () позволяют задать соответственно название, год издания и имя автора книги — нового объекта CоBооk. При передачи в качестве входного аргумента BSTR-строки происходит переразмещение в памяти соответствующей BSTR-строки — члена класса. Для этого используется функция SysReAllocstring ().

Метод GetInfо () возвращает информацию о книге в строке типа BSTR. Вся информация о книге хранится в экземпляре класса CоBооk в виде BSTR-cтрок и целого числа. В процессе формирования результирующей строки все BSTR-строки преобразуются в ANSI-строки. Для выполнения преобразования BSTR-строки в ANSI-строку применяется функция wcstombs (). Первый параметр задает буфер для ANSI-строки, второй — BSTR-строку, третий — размер буфера. Функция SysStringien () позволяет определить длину BSTR-строки в символах. Размер буфера для соответствующей ANSI-строки выбирается в два раза превосходящим длину BSTR-строки, т. к. некоторые Unicode-символы представляются двумя ANSI-символами. Далее в буфер pszText помещается вся выводимая информация, выделяется память под возвращаемую BSTR-строку *pbstrInfо и вызывается функция преобразования ANSI-строки pszText в BSTR-строку *pbstrInfо-mbstowcs().

Для выделения памяти под возвращаемую строку используется функция SysAlloSstringLen (). Первый параметр задает BSTR-строку, первые символы которой, в количестве равном второму параметру, заносятся в новую строку. Задав в качестве первого параметра null мы получаем неинициализированную BSTR-строку длины, заданной вторым параметром.

Последнее действие — освобождение памяти, выделенной под буферы.

Далее определяется и реализуется класс CоJournal, порожденный от интерфейса IJournal. Так как интерфейс IJournal был сам порожден от интерфейса IPub, а последний — от стандартного интерфейса IUnknown, то класс CоJournal должен реализовать чисто виртуальные методы всех этих интерфейсов. Данный класс мало отличается от класса CоBооk, в связи с чем комментарии минимальны.

//////////////////////////////////////////////////

// СоJournal.h: заголовочный файл для класс СоJournal.

//////////////////////////////////////////////////

#ifndef _CoJournal_

#define _CoJournal_

#include "IJournal.h"

#include "iid.h"

class CoJournal:

          public IJournal

{

public:

          CoJournal ();

          virtual ~CoJournal();

          // IUnknown

          STDMETHODIMP Querylnterface(REFIID riid, void** pIFace);

          STDMETHODIMP_(ULONG) AddRef();

          STDMETHODIMP_(ULONG) Release();

          // IPub

           STDMETHOD(SetTitle)(BSTR bstrTitle);

           STDMETHOD(SetYear)(int nYear);

           STDMETHOD(Getlnfo)(BSTR* pbstrlnfo);

           // IJournal

           STDMETHOD(SetNumber)(int nNumber);

private:

           ULONG m_refCount; // Счетчик ссылок

           BSTR m_bstrTitle; // Название публикации

           int m_nYear; // Год публикации

           int m nNumber; // Номер журнала

};

#endif

И теперь реализация класса CоJournal

//////////////////////////////////////////////////

// СоJournal.cpp: реализация класса CoJournal.

//////////////////////////////////////////////////

#include <stdio.h>

#include "CoJournal.h"

#include <stdio.h>

#include "CoJournal.h"

extern ULONG g_objCount; // Счетчик числа объектов

//////////////////////////////////////////////////

// Конструктор и деструктор

//////////////////////////////////////////////////

CoJournal::CoJournal()

{

          m_refCount = 0;

          ++g_obj Count;

          m_bstrTitle = SysAllocString(L"");

}

CoJournal::~CoJournal()

{

          -- g_objCount;

          if(m_b strTitle)

                        SysFreeString(m_bstrTitle);

}

// IUnknown

1 ... 197 198 199 200 201 202 203 204 205 ... 361
Перейти на страницу:

Комментарии
Минимальная длина комментария - 25 символов.
Комментариев еще нет. Будьте первым.
Правообладателям Политика конфиденциальности