Сущность технологии COM




Динамическая композиция - часть 6


class XTruck : public ITruck { ... }; class XMonsterTruck : public IMonsterTruck { ... }; class XBicycle : public IBicycle { ... }; : : : };

В этом классе в случае, когда не используется ни один из интерфейсов, объект платит за пустой кэшированный указатель только четырьмя дополнительными байтами. Когда приходит запрос QueryInterfасе на один из десяти транспортных интерфейсов, то память выделена для нового отделяемого интерфейса один раз и кэширована для более позднего использования:

STDMETHODIMP GenericVehicle::QueryInterface(REFIID riid ,void **ppv) { if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(this); else if (riid == IID_ITruck) { if (m_pTearOff == 0) // no tearoff yet, make one // отделяемого интерфейса еще нет, создаем один m_pTearOff = new XTruck(this); if (m_pTearOff) // tearoff exists, let tearoff QI // отделяемый интерфейс существует, пусть это QI return m_pTearOff->QueryInterface(riid, ppv); else // memory allocation failure // ошибка выделения памяти return (*ppv = 0), E_NOINTERFACE; } else if (riid == IID_IMonsterTruck) { if (in_pTearOff == 0) // no tearoff yet, make one // отделяемого интерфейса еще нет, создаем один m_pTearOff = new XMonsterTruck(this); if (m_pTearOff) // tearoff exists, let tearoff QI // отделяемый интерфейс существует, пусть это QI return m_pTearOff->QueryInterface(riid, ppv); else // memory allocation failure // ошибка выделения памяти return (*ppv = 0), E_NOINTERFACE; } else ... : : : }

На основе показанной здесь реализации QueryInterface на каждый объект будет приходиться по большей части по одному отделяемому интерфейсу. Это значит, что в случае отсутствия запросов на транспортные интерфейсы объект будет тратить в сумме 12 байт (vptr IUnknown + счетчик ссылок + кэшированный указатель на отделяемый интерфейс). Если транспортный интерфейс запрошен, то объект будет тратить в сумме от 24 до 28 байт (исходные 12 байт + наследующий Vehicle vptr + счетчик ссылок + обратный указатель на главный объект + (необязательно) служебная запись malloc (memory allocation - выделение памяти)).




Содержание  Назад  Вперед