Читаем Сущность технологии СОМ. Библиотека программиста полностью

Допуская, что интерфейсы IBoat и IPlane подвергнуты подобной операции, можно реализовывать различные версии GetMaxSpeed простым наследованием от расширенных версий интерфейсов и переопределением неконфликтных версий каждого метода GetMaxSpeed:

class CarBoatPlane: public IXCar, public IXBoat, public IXPlane

{

public:

// Unknown methods – методы IUnknown

STDMETHODIMP QueryInterface(REFIID, void**);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

// IVehicle methods – методы IVehicle

// do not override GetMaxSpeed!

// не подменяем GetMaxSpeed!

// ICar methods – методы ICar

STDMETHODIMP Brake(void);

// IBoat methods – методы IBoat

STDMETHODIMP Sink(void);

// IXPlane methods – методы IXPlane

STDMETHODIMP TakeOff(void);

// upcalled from IXCar::GetMaxSpeed

// вызвано из IXCar::GetMaxSpeed

STDMETHODIMP GetMaxCarSpeed(long *pval);

// upcalled from IXBoat::GetMaxSpeed

// вызвано из IXBoat::GetMaxSpeed

STDMETHODIMP GetMaxBoatSpeed(long *pval);

// called from IXPlane::GetMaxSpeed

// вызвано из IXPlane::GetMaxSpeed

STDMETHODIMP GetMaxPlaneSpeed(long *pval);

}

Рисунок 4.6 иллюстрирует представление этого класса и форматы таблиц vtbl. Отметим, что конфликтный метод GetMaxSpeed не реализован в этом классе. Поскольку каждый из базовых классов CarBoatPlane подменяет этот чисто виртуальный метод, то CarBoatPlane не нуждается в создании своей собственной реализации. Действительно, если бы в CarBoatPlane нужно было подменить GetMaxSpeed, то одна его реализация этого метода подменила бы версии, вызываемые из каждого базового класса, аннулировав результат использования IXCar, IXBoat и IXPlane. В силу этой проблемы данная технология годится только в тех ситуациях, когда можно быть уверенным, что класс реализации (или любые возможные производные классы) никогда не станет подменять конфликтный метод.

Другой способ обеспечения множественных реализации конфликтных методов состоит в том, чтобы усилить правила IUnknown . Спецификация СОМ не требует, чтобы объект был реализован как класс C++. Хотя существует весьма естественное соответствие между объектами СОМ и классами C++, базирующимися на множественном наследовании, это всего лишь одна из возможных технологий реализации. Для создания объекта СОМ может быть использована любая программная технология, производящая таблицы vtbl в нужном формате и удовлетворяющая правилам СОМ для QueryInterface. Один стандартный метод разрешения конфликтов имен состоит в реализации интерфейсов с конфликтующими именами как отдельных классов C++ и последующей компоновке целевого класса C++ из экземпляров этих отдельных классов. Для гарантии того, что каждый из этих составных элементов данных появится во внешнем мире как единый объект СОМ, часто назначается одна главная реализация QueryInterface, которой каждый составной элемент данных будет передавать функции. Следующий код демонстрирует эту технологию:

class CarPlane

{

LONG m_cRef;

CarPlane(void) : m_cRef(0) {}

public:

// Main IUnknown methods

// Главные методы IUnknown

STDMETHODIMP QueryInterface(REFIID, void**);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

private:

// define nested class that implements ICar

// определяем вложенный класс, реализующий

ICar struct XCar : public ICar

{

// get back pointer to main object

// получаем обратный указатель на главный объект

inline CarPlane* This();

STDMETHODIMP QueryInterface(REFIID, void**);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

STDMETHODIMP GetMaxSpeed(long *pval);

STDMETHODIMP Brake(void);

};

// define nested class that implements IPlane

// определяем вложенный класс, реализующий IPlane

struct XPlane : public IPlane {

// Get back pointer to main object

// получаем обратный указатель на главный объект

inline CarPlane* This();

STDMETHODIMP QueryInterface(REFIID, void**);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

STDMETHODIMP GetMaxSpeed(long *pval);

STDMETHODIMP TakeOff(void);

};

// declare instances of nested classes

// объявляем экземпляры вложенных классов

XCar m_xCar;

XPlane m_xPlane;

};

Использование вложенных классов не является обязательным, но оно подчеркивает, что эти подчиненные классы не имеют смысла вне контекста класса CarPlane. Рисунок 4.7 показывает двоичное размещение этого класса и размещения соответствующих vtbl .

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

STDMETHODIMP CarPlane::XCar::GetMaxSpeed(long *pn) {

// set *pn to max speed for cars

// устанавливаем *pn для максимальной скорости автомобилей

}

STDMETHODIMP CarPlane::XPlane::GetMaxSpeed(long *pn) {

// set *pn to max speed for planes

// устанавливаем *pn для максимальной скорости самолетов

}

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных