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

Страница: 61 из 528

Поскольку класс реализации порождается из каждого интерфейса, который он выставляет, реализация Dynamic_Cast в FastString может просто использовать явные статические приведения типа (explicit static casts), чтобы ограничить область действия указателя this, основанного на подтипе, который запрашивается клиентом:

void *FastString::Dynam1c_Cast(const char *pszType)

{

if (strcmp(pszType, «IFastString») == 0) return static_cast(this);

else if (strcmp(pszType, «IPersistentObject») == 0) return static_cast(this);

else if (strcmp(pszType, «IExtensibleObject») == 0) return static_cast(this);

else return 0;

// request for unsupported interface

// запрос на неподдерживаемый интерфейс

}

Так как объект порождается от типа, используемого в этом преобразовании, оттранслированные версии операторов преобразования просто добавляют определенное смещение к указателю объекта this, чтобы найти начало представления базового класса.

Отметим, что после запроса на общий базовый интерфейс IExtensibleObject реализация статически преобразуется в IFastString. Это происходит потому, что интуитивная версия (intuitive version) оператора

return static_cast(this);

неоднозначна, так как и IFastString, и IPersistentObject порождены от IExtensibleObject. Если бы IExtensibleObject был виртуальным базовым классом как для IFastString, так и для IPersistentObject, то данное преобразование не было бы неоднозначным и оператор бы оттранслировался. Тем не менее, применение виртуальных базовых классов добавляет на этапе выполнения ненужную сложность в результирующий объект и к тому же вносит зависимость от транслятора. Дело в том, что виртуальные базовые классы являются всего лишь особенностями языка C++, которые имеют несколько специфических реализации.



Управление ресурсами



Еще одна проблема поддержки нескольких интерфейсов из одного объекта становится яснее, если исследовать схему использования клиентом метода DynamicCast . Рассмотрим следующую клиентскую программу:

void f(void)

{

IFastString *pfs = 0;

IPersistentObject *ppo = 0;

pfs = CreateFastString(«Feed BOB»);

if (pfs) {

ppo = (IPersistentObject *) pfs->Dynami cCast(«IPersistentObject»);

if ( !ppo) pfs->Delete();

else { ppo->Save(«C:\\autoexec.

|< Пред. 59 60 61 62 63 След. >|

Java книги

Контакты: [email protected]