Динамическое использование интерфейсов
В этом примере продемонстрировано далеко не оптимальное решение, так как проверка типа производится дважды. Первый раз – при использовании отражения для проверки поддержки интерфейса в макросе IS. А еще раз проверка производится автоматически – при выполнении динамического приведения типа, в этом случае, если интерфейс не поддерживается, возникает исключение. Результат работы программы приведен ниже. Обратите внимание, что при выполнении программы действительно не возникает исключения.
Customer1 pCustl does not support ICustomer2 interface Customer2 Customer2::ShowCustomers: succeeded
А вот и перевод:
Customer1 pCustl не поддерживает интерфейс ICustomer2 Customer2 Customer2:: ShowCustomers: успешно
Оператор dynamic_cast
Результатом выполнения оператора dynamic_cast является непосредственно указатель на интерфейс. В случае, если интерфейс не поддерживается, значение указателя устанавливается равным нулю. Используем этот факт для создания программы, в которой проверка поддержки интерфейса производится один раз. Приведенный ниже фрагмент взят из примера CastThenTestForNull, отличающегося от предыдущего, TestlnterfaceBeforeCast, тем, что в нем производится проверка равенства нулю результата динамического приведения типа.
void main(void) // главный { Customerl *pCustl = new Customer!; // нет ICustomer2 Console::WriteLine(pCustl › GetType()); // Использовать оператор С ++ dynamic_cast, чтобы проверить // наличие ICustomer2 ICustomer2 *plcust2 = dynamic_cast<ICustomer2 *>(pCustl); if (plcust2!= 0) p!cust2 › ShowCustomers(-1); else Console::WriteLine ("pCustl does not support ICustomer2 interface"); // ("pCustl не поддерживает интерфейс ICustomer2"); Customer2 *pCust2 = new Customer2; // да, есть ICustomer2 Console::WriteLine(pCust2 › GetType()); // Использовать оператор С ++ dynamic_cast, чтобы проверить // наличие ICustomer2 plcust2 = dynamic_cast<ICustomer2 *>(pCust2); if (plcust2!= 0) plcust2 › ShowCustomers(-1); else Console::WriteLine ("pCust2 does not support ICustomer2 interface"); // ("pCust2 не поддерживает интерфейс ICustomer2"); }
Результат выполнения программы CastThenTestForNull показывает, что действительно, исключения не возникает, но проверка поддержки интерфейса при этом производится всего один раз для каждого из объектов.
Customer1 pCustl does not support ICustomer2 interface Customer2 ICustomer2::ShowCustomers: succeeded
Вот перевод этой выдачи:
Customer1 pCustl не поддерживает интерфейс ICustomer2 Customer2 ICustomer2:: ShowCustomers: успешно
Если вы знакомы с моделью компонентных объектов Microsoft (COM), проверка поддержки классом интерфейса вам должна быть хорошо знакома.