Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Программирование -> C/C++ -> Сущность технологии COM


Объекты классов

Основное требование всех СОМ-классов состоит в том, что они должны иметь объект класса. Объект класса - это единственный экземпляр (синглетон), связанный с каждым классом, который реализует функциональность класса, общую для всех его экземпляров. Объект класса ведет себя как метакласс по отношению к заданной реализации, а реализуемые им методы выполняют роль статических функций-членов из C++. По логике вещей, может быть только один объект класса в каждом классе; однако в силу распределенной природы СOМ каждый класс может иметь по одному объекту класса на каждую хост-машину (host machine), на учетную запись пользователя или на процесс, - в зависимости от того, как используется этот класс. Первой точкой входа в реализацию класса является ее объект класса.

Объекты класса являются очень полезными программистскими абстракциями. Объекты класса могут вести себя как известные объекты (когда их идентификатор CLSID выступает в качестве имени объекта), которые позволяют нескольким клиентам связываться с одним и тем же объектом, определенным с помощью данного CLSID. В то время как системы в целом могли быть созданы с использованием исключительно объектов класса, объекты класса часто используются как посредники (brokers) при создании новых экземпляров класса или для того, чтобы найти имеющиеся экземпляры, определенные с помощью какого-нибудь известного имени объекта. При использовании в этой роли объект класса обычно объявляет только один или два промежуточных интерфейса, которые позволят клиентам создать или найти те экземпляры, которые в конечном счете будут выполнять нужную работу. Например, рассмотрим описанный ранее интерфейс IАре. Объявление интерфейса IАре не нарушит законы СОМ для объекта класса:

class GorillaClass : public IApe {
  public:
      // class objects are singletons, so don't delete
      // объекты класса существуют в единственном экземпляре,
      // так что не удаляйте их
    IMPLEMENT_UNKNOWN_NO_DELETE (GorillaClass)
    BEGIN_INTERFACE_TABLE(GorillaClass) 
      IMPLEMENTS_INTERFACE(IApe)
    END_INTERFACE_TABLE()
      // IApe methods
      // методы IApe
    STDMETHODIMP EatBanana(void);
    STDMETHODIMP SwingFromTree(void);
    STDMETHODIMP get_Weight(long *plbs);
};

Если для данного класса C++ может существовать лишь один экземпляр (так ведут себя все объекты классов в СОМ), то в любом заданном экземпляре может быть только одна горилла (gorilla). Для некоторых областей одноэлементных множеств достаточно. В случае с гориллами, однако, весьма вероятно, что клиенты могут захотеть создавать приложения, которые будут использовать несколько различных горилл одновременно. Чтобы обеспечить такое использование, объект класса не должен экспортировать интерфейс IApe, а вместо этого должен экспортировать новый интерфейс, который позволит клиентам создавать новых горилл и/или находить известных горилл по их имени. Это потребует от разработчика определить два класса C++: один для реализации объекта класса и другой для реализации действительных экземпляров класса. Для реализации гориллы класс C++, который определяет экземпляры гориллы, будет реализовывать интерфейс IApe:

class Gorilla : public IApe {
  public:
      // Instances are heap-based, so delete when done 
      // копии размещены в куче, поэтому удаляем после выполнения 
    IMPLEMENT_UNKNOWN() 
    BEGIN_INTERFACE_TABLE()
      IMPLEMENTS_INTERFACE(IApe) 
    END_INTERFACE_TABLE() 
      // IApe methods 
      // методы IApe 
    STDMETHODIMP EatBanana(void);
    STDMETHODIMP SwingFromTree(void);
    STDMETHODIMP get_Weight(long *plbs):
};

Второй интерфейс понадобится для определения тех операций, которые будет реализовывать объект класса Gorilla:

[object, uuid(753A8AAC-A7FF-11d0-8C30-0080C73925BA)]
interface IApeClass : IUnknown {
  HRESULT CreateApe([out, retval] IApe **ppApe);
  HRESULT GetApe([in] long nApeID, [out, retval] IApe **ppApe);
  [propget] HRESULT AverageWeight([out, retval] long *plbs);
}

Получив это определение интерфейса, объект класса будет реализовывать методы IApeClass или путем создания новых экземпляров С++-класса Gorilla (в случае CreateApe), или преобразованием произвольно выбранного имени объекта (в данном случае типа integer) в отдельный экземпляр (в случае GetApe):

class GorillaClass : public IApeClass {
  public:
    IMPLEMENT_UNKNOWN_NO_DELETE(GorillaClass) 
    BEGIN_INTERFACE_TABLE(GorillaClass)
      IMPLEMENTS_INTERFACE(IApeClass) 
    END_INTERFACE_TABLE()
    STDMETHODIMP CreateApe(Ape **ppApe) { 
        if ((*ppApe = new Gorilla) == 0) 
            return E_OUTOFMEMORY;
        (*ppApe)->AddRef();
        return S_OK;
    }

    STDMETHODIMP GetApe(long nApeID, IApe **ppApe) { 
      // assume that a table of well-known gorillas is 
      // being maintained somewhere else 
      // допустим, что таблица для известных горилл 
      // поддерживается где-нибудь еще

      extern Gorilla *g_rgWellKnownGorillas[];
      extern int g_nMaxGorillas;
 
      // assert that nApeID is a valid index 
      // объявляем, что nApeID - допустимый индекс
      *ррАре = 0;
      if (nApeID > g_nMaxGorillas || nApeID < 0) 
          return E_INVALIDARG;
      // assume that the ID is simply the index into the table 
      // допустим, что ID - просто индекс в таблице 
      if ((*ppApe = g_rgWellKnownGorillas[nApeID]) == 0) 
          return E_INVALIDARG;
      (*ppApe)->AddRef();
      return S_OK;
    }

    STDMETHODIMP get_AverageWeight(long *plbs) { 
      extern  *g_rgWellKnownGorillas[];
      extern int g_nMaxGorillas;
      *plbs = 0; 
      long lbs;
      for (int i = 0; i < g_nMaxGorillas; i++) { 
        g_rgWellKnownGorillas[i]->get_Weight(&lbs);
        *plbs += lbs;
      }

      // assumes g_nMaxGorillas is non-zero 
      // предполагается, что g_nMaxGorillas ненулевой 
      *plbs /= g_nMaxGorillas;
      return S_OK;
    } 
};

Отметим, что в этом коде предполагается, что внешняя таблица известных горилл уже поддерживается - или самими копиями Gorilla, или каким-нибудь другим посредником (agent).

Активация
Использование SCM
Классы и серверы
Обобщения
Оптимизации
Снова интерфейс и реализация
Моникеры и композиция
Моникеры и сохраняемость
Время жизни сервера
Классы и IDL
Эмуляция классов
Категории компонентов
Где мы находимся?

 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.