Outer::Outer(void)
{
++m_cRef;
// protect against delete this
// защищаем против удаления this
CoCreateInstance(CLSID_Inner, this, CLSCTX_ALL, IID_IUnknown, (void**)&m_pUnkInner);
–m_cRef;
// allow delete this
// позволяем удалить this }
Данная методика стабилизации предотвращает преждевременное разрушение, когда внутренний объект освобождает указатели, которые он, быть может, получил в свой код инициализации. Эта методика настолько общепринята, что большинство СОМ-оболочек программирования включают в себя явный метод перекрытия ( overridable ), который работает внутри области действия пары инкремент/декремент. В MFC (Microsoft Foundation Classes – библиотека базовых классов Microsoft) этот метод называется CreateAggregates , в ATL – FinalConstruct .
Поскольку показанные выше методики реализации агрегируемого объекта не требуют никаких дополнительных базовых классов, кроме классов C++, то альтернативная форма макроса IMPLEMENT_UNKNOWN может прозрачно реализовать раздвоенную реализацию IUnknown . Определение исходного класса:
class Car : public ICar
{
Car(void);
IMPLEMENT_UNKNOWN(Car)
BEGIN_INTERFACE_TABLE(Car)
IMPLEMENTS_INTERFACE(ICar)
IMPLEMENTS_INTERFACE(IVehicle)
END_INTERFACE()
// IVehicle methods
// методы IVehicle
STDMETHODIMP GetMaxSpeed(long *pn);
// ICar methods
// методы ICar
STDMETHODIMP Brake(void);
};
просто переводится в следующее:
class Car : public ICar
{
Car(void);
//indicate that aggregation is required
// показываем, что требуется агрегирование
IMPLEMENT_AGGREGATABLE_UNKNOWN(Car)
BEGIN_INTERFACE_TABLE(Car)
IMPLEMENTS_INTERFACE(ICar)
IMPLEMENTS_INTERFACE(IVehicle)
END_INTERFACE()
// IVehicle methods
// методы IVehicle
STDMETHODIMP GetMaxSpeed(long *pn);
// ICar methods
// методы ICar
STDMETHODIMP Brake(void);
};
Встроенное расширение макроса IMPLEMENT_AGGREGATABLE_UNKNOWN включено в код, приложенный к этой книге.
Не все классы способны к агрегированию. Для того чтобы выставить неагрегируемые классы как часть индивидуальности другого объекта, необходимо, чтобы внешние объекты явно передавали вызовы методов внутренним объектам. Эта технология СОМ часто называется включением ( containment ).
Как показано на рис. 4.9, включение не требует никакого участия со стороны внутреннего объекта. В то же время требуется, чтобы во внешнем объекте производились реализации каждого интерфейса, выставляемого внутренним объектом. Эти внешние реализации просто передают клиентские запросы внутреннему объекту. Включение СОМ не требует никаких особых забот касательно правил идентификации СОМ, так как внутренний объект никогда не доступен клиенту впрямую и поэтому никогда непосредственно не внедряется в иерархию типов внешнего объекта. Хотя СОМ-включение входит в терминологию СОМ, оно не требует никаких особых программистских ухищрений. Фактически включаемый объект не может обнаружить, что внешний объект переадресовывает запросы его методов от действующего клиента.
В данной главе обсуждались законы идентификации в СОМ. В этих законах определено, что означает быть объектом СОМ. Законы идентификации СОМ предоставляют разработчику объекта потрясающую гибкость при разделении реализации объекта. В качестве технологии для освобождения подсчета ссылок для каждого интерфейса была представлена композиция. Для сокращения размножения vptr, а также для более эффективного управления состоянием объекта были описаны отделяемые интерфейсы. Затем было показано агрегирование в качестве способа создания одной идентификационной единицы ( identity ) из двух или более двоичных компонентов. Каждая из этих технологий позволяет более чем одному объекту выступать в качестве одной идентификационной единицы СОМ. Каждая технология имеет свои преимущества, и использование любой из них или всех вместе полностью скрыто от клиентов объекта.
STDMETHODIMP CMyClass::MethodX(void) {
EnterCr1t1calSect1on(&m_cs);
if (TryToPerformX() == false)
return E_UNEXPECTED:
LeaveCriticalSect1on(&m_cs);
return S_OK; }
Аноним, 1996
В предыдущей главе обсуждались основы идентификации в СОМ и было формально определено, что именно отличает объекты СОМ от объектов памяти с произвольной организацией. Были представлены правила IUnknown и способы использования этих правил для придания разработчику объектов максимальной гибкости. В данной главе уточняется понятие идентификации в СОМ с учетом базисных элементов (примитивов) операционной системы (например, потоков, процессов), а также распределенного доступа. Этот альянс базисных элементов системы и распределения формируют основу архитектуры удаленного доступа СОМ.
Читать дальше