На этом шаге мы рассмотрим назначение и особенности использования класса _com_ptr_t.
Класс _com_ptr_t - это шаблонный класс, инкапсулирующий указатель на СОМ-интерфейс. Кроме того, в нем имеется дополнительный код, упрощающий поддержку счетчика использования. Объект _com_ptr_t вызывает от Вашего имени методы инкапсулированного в нем интерфейса IUnknown::AddRef() и IUnknown::Release(), обеспечивая корректное управление существованием СОМ-объектов. AddRef() вызывается автоматически при создании объекта _com_ptr_t в качестве копии существующего указателя на интерфейс, a Release() - когда объект _com_ptr_t выходит из области видимости.
Хотя "интеллектуальный" указатель и позволяет создать более удобочитаемый исходный код, не теряйте бдительности - Вы всегда должны понимать, что происходит с СОМ-объектом в Вашем коде, а также отслеживать вызовы AddRef() и Release() - даже если вместо Вас этим занимается "интеллектуальный" указатель.
Самый простой путь сформировать определенный тип интерфейса на основе шаблона _com_ptr_t - использовать макрос _COM_SMARTPTR_TYPEDEF. В качестве параметров он получает имя интерфейса и его уникальный GUID и объявляет экземпляр _com_ptr_t с именем, состоящим из имени интерфейса с суффиксом Ptr. Например, в файле, содержащем заголовочные файлы EncodeServer.h и ЕnсоdeServer_i.c, следующая строка создаст на базе шаблона _com_ptr_t интерфейс IEncoderPtr:
_COM_SMARTPTR_TYPEDEF(IEncoder, __uuidof(IEncoder));
Экземпляры этого типа способны вызывать функцию-член СгеаteInstance() класса _com_ptr_t для получения указателя на интерфейс СОМ-сервера следующим образом:
IEncoderPtr pEnc; pEnc.CreateInstance(CLSID_Encoder);
Далее этот указатель используют для вызова методов интерфейса помошью перегруженного в _com_ptr_t оператора ->:
int n = 3;
HRESULT hr = pEnc->put_Key(n);
Обратите внимание, что функции-члены _com_ptr_t вызываются оператором "точка" (как в обращении к CreateInstance()), а методы интерфейса - с помощью перегруженного оператора -> (как в только что показанном обращении к put_Key()).
Кроме того, объекты _com_ptr_t допустимо создавать на базе существующего указателя на СОМ-интерфейс или же скопировать другой объект _com_ptr_t. В справочной системе Visual C++ более подробно описано, как вызывать методы AddRef() и Release() из операторов присваивания и конструкторов копий.
На следующем шаге мы рассмотрим класс _bstr_t.