Полиморфизм на этапе выполнения
Полиморфизм на этапе выполнения
Управление реализациями классов с использованием абстрактных базовых классов как интерфейсов открывает целый мир новых возможностей в терминах того, что может случиться на этапе выполнения. Напомним, что DLL FastString экспортирует только один идентификатор – CreateFastString. Теперь пользователю легко динамически загрузить DLL, используя по требованию LoadLibrary, и разрешить этой единственной точке входа использовать GetProcAddress:
IFastString *CallCreateFastString(const char *psz)
{
static IFastString * (*pfn)(const char *) = 0;
if (!pfn) {
// init ptr 1st time through
// первое появление ptr
const TCHAR szDll[] = TEXT(«FastString.DLL»);
const char szFn[] = «CreateFastString»;
HINSTANCE h = LoadLibrary(szDll);
if (h) *(FARPROC*)&pfn = GetProcAddress(h, szFn); }
return pfn ? pfn(psz) : 0;
}
Эта методика имеет несколько возможных приложений. Одна из причин ее использования – предотвращение ошибок, генерируемых операционной системой при работе на машине, где не установлена реализация объектов. Приложения, использующие дополнительные системные компоненты, такие как WinSock или MAPI, используют похожую технику для запуска приложений на машинах с минимальной конфигурацией. Поскольку клиенту никогда не нужно компоновать импортируемую библиотеку DLL, он не зависит от загрузки DLL и может работать на машинах, на которых DLL вообще не установлена. Другой причиной для использования этой методики может быть медленная инициализация адресного пространства. Кроме того, DLL не загружается автоматически во время инициализации; и если в действительности реализация объекта не используется, то DLL не загрузится никогда. Другими преимуществами этого способа являются ускорение запуска клиента и сохранение адресного пространства для длительных процессов, которые могут никогда реально не использовать DLL.
Возможно, одним из наиболее интересных применений этой методики является возможность для клиента динамически выбирать между различными реализациями одного и того же интерфейса. Если описание интерфейса IFastString дано как общедоступное (publicly available), то ничто не препятствует как исходному конструктору (implementor) FastString, так и любым сторонним средствам реализации порождать дополнительные классы реализации от того же самого интерфейса. Подобно исходной реализации класса FastString, эти новые реализации будут иметь такое двоичное представление, что будут совместимы на двоичном уровне с исходным классом интерфейса. Все, что должен сделать пользователь, чтобы добиться полностью совместимых («plug-compatible») реализаций, – это определить правильное имя файла для желаемой реализации DLL.
Чтобы понять, как применить эту методику, предположим, что исходная реализация IFastString выполняла поиск слева направо. Это прекрасно для языков, анализируемых слева направо (например, английский, французский, немецкий). Для языков, анализируемых справа налево, предпочтительней вторая реализация IFastString, осуществляющая поиск справа налево. Эта альтернативная реализация может быть построена как вторая DLL с характерным именем (например, FastStringRL.DLL). Пусть обе DLL установлены на машине конечного пользователя, тогда он может выбрать нужный вариант IFastString простой загрузкой требуемой DLL на этапе выполнения:
IFastString * CallCreateFastString(const char *psz, bool bLeftToRight = true)
{
static IFastString * (*pfnlr)(const char *) = 0;
static IFastString * (*pfnrl)(const char *) = 0;
IFastString *(**ppfn) (const char *) = &pfnlr;
const TCHAR *pszDll = TEXT(«FastString.DLL»);
if (!bLeftToRight) { pszDll = TEXT(«FastStringRL.DLL»);
ppfn = &pfnrl; }
if (!(*ppfn)) {
// init ptr 1st time through
// первое появление ptr
const char szFn[] = «CreateFastString»;
HINSTANCE h = LoadLibrary(pszDll);
if (h) *(FARPROC*)ppfn = GetProcAddress(h, szFn); }
return (*ppfn) ? (*ppfn)(psz) : 0;
}
Когда клиент вызывает функцию без второго параметра,
pfs = CallCreateFastString(«Hi Bob!»);
n = pfs->Find(«ob»);
то загружается исходная DLL FastString, и поиск идет слева направо. Если же клиент указывает, что строка написана на разговорном языке, анализируемом справа налево:
pfs = CallCreateFastString(«Hi Bob!», false);
n = pfs->Find(«ob»);
то загружается альтернативная версия DLL (FastStringRL.DLL ), и поиск будет начинаться с крайней правой позиции строки. Главное здесь то, что вызывающие операторы CallCreateFastString не заботятся о том, какая из DLL используется для реализации методов объекта. Существенно лишь то, что указатель на совместимый с IFastString vptr возвращается функцией и что vptr обеспечивает успешное и семантически корректное функционирование. Эта форма полиморфизма на этапе выполнения чрезвычайно полезна при создании системы, динамически скомпонованной из двоичных компонентов.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Работа с данными процессоров на этапе выполнения
Работа с данными процессоров на этапе выполнения Для динамического создания данных, связанных с процессорами, в ядре реализован специальный распределитель памяти, который имеет интерфейс, аналогичный kmalloc(). Эти функции позволяют создать экземпляр участка памяти для
Элемент <xsl:element>: создание новых элементов на этапе выполнения
Элемент <xsl:element>: создание новых элементов на этапе выполнения Новые элементы можно создавать при помощи элемента <xsl:element>, который очень удобен для задания имени нового элемента на этапе выполнения.У этого элемента три атрибута:• name (обязательный). Имя
64. Разумно сочетайте статический и динамический полиморфизм
64. Разумно сочетайте статический и динамический полиморфизм РезюмеСтатический и динамический полиморфизм дополняют друг друга. Следует ясно представлять себе их преимущества и недостатки, чтобы использовать каждый из них там, где он дает наилучшие результаты, и
90. Избегайте явного выбора типов — используйте полиморфизм
90. Избегайте явного выбора типов — используйте полиморфизм РезюмеИзбегайте явного выбора типа объекта для настройки поведения. Используйте шаблоны и виртуальные функции для того, чтобы поведение объекта определялось его типом, а не вызывающим
Правило 41: Разберитесь в том, что такое неявные интерфейсы и полиморфизм на этапе компиляции
Правило 41: Разберитесь в том, что такое неявные интерфейсы и полиморфизм на этапе компиляции В мире объектно-ориентированного программирования преобладают явные интерфейсы и полиморфизм на этапе исполнения. Например, рассмотрим следующий (бессмысленный) класс:class Widget
1.1.3. Полиморфизм
1.1.3. Полиморфизм Термин «полиморфизм», наверное, вызывает самые жаркие семантические споры. Каждый знает, что это такое, но все понимают его по-разному. (Не так давно вопрос «Что такое полиморфизм?» стал популярным во время собеседования при поступлении на работу. Если его
Полиморфизм
Полиморфизм Третьим принципом ООП является полиморфизм. Он характеризует способность языка одинаково интерпретировать родственные объекты. Эта особенность объектно-ориентированного языка позволяет базовому классу определить множество членов (формально называемых
Принудительный полиморфизм: абстрактные методы
Принудительный полиморфизм: абстрактные методы Если класс является абстрактным базовым классом, он может определять любое число абстрактных членов (их аналогами в C++ являются "чистые" виртуальные функции). Абстрактные методы могут использоваться тогда, когда требуется
Выявление ошибки на этапе анализа кода
Выявление ошибки на этапе анализа кода Чтобы обнаружить загадочные URL, просмотрите весь серверный код Web–приложения и выпишите точки входа, через которые данные поступают из сети. Ищите следующие конструкции: Для скрытых полей форм задача несколько проще. Ищите в коде
Выявление ошибки на этапе анализа кода
Выявление ошибки на этапе анализа кода Прежде всего найдите все точки входа в приложение из сети. Для каждой точки входа определите, используется ли протокол SSL. API сильно зависит от библиотеки и языка, но поиска по словам «SSL» и «TLS» без учета регистра обычно хватает. Если
Выявление ошибки на этапе анализа кода
Выявление ошибки на этапе анализа кода Столкнувшись с парольной защитой, довольно просто идентифицировать риски. И большинство ее свойств легко проверить. По большей части аспекты, вызывающие возражения, считаются допустимым риском, хотя это и зависит от конкретных
Выявление ошибки на этапе анализа кода
Выявление ошибки на этапе анализа кода С точки зрения управления доступом все довольно просто: ищите места, где задаются права на доступ к объекту. Тщательно анализируйте те участки кода, где устанавливаются элементы управления доступом или разрешения. Далее проверьте
Полиморфизм
Полиморфизм Полиморфизм представляет собой способность вируса в процессе работы менять свой код таким образом, чтобы максимально затруднить процесс своего обнаружения путем сигнатурного сканирования и частично эвристики.Особо следует отметить тот факт, что и сама
Полиморфизм
Полиморфизм При наследовании, требование статической типизации, о котором говорилось выше, становится ограничивающим, если бы оно означало, что каждая сущность типа C может быть связана только с объектом точно такого же типа С. Например в системе управления навигацией
Полиморфизм
Полиморфизм Иерархии наследования позволяют достаточно гибко работать с объектами, сохраняя надежность статической типизации. Поддерживающие их методы: полиморфизм и динамическое связывание - одни из самых фундаментальных аспектов архитектуры ПО, обсуждаемой в этой