для реализации полиморфизма. Если у вас нет указателя на базовый класс
указывая на производный объект, здесь у вас не может быть полиморфизма.
Одной из ключевых особенностей производных классов является то, что указатель на
Производный класс совместим по типу с указателем на его базовый класс.
Полиморфизм - это искусство воспользоваться этим простым, но
мощная и универсальная функция, которая приносит объектно-ориентированный
Методологии в полном объеме.
В C ++ существует специальное отношение тип / подтип, в котором база
указатель класса или ссылка может обращаться к любому из его производного класса
подтипы без вмешательства программиста. Эта способность манипулировать
более одного типа с указателем или ссылкой на базовый класс
о котором говорят как о полиморфизме.
Подтип полиморфизма позволяет нам написать ядро нашего приложения
независимо от отдельных типов, которыми мы хотим манипулировать. Скорее мы
запрограммировать публичный интерфейс базового класса нашей абстракции
через указатели и ссылки на базовый класс. Во время выполнения фактическая
тип, на который ссылаются, разрешается, и соответствующий экземпляр
общедоступный интерфейс вызывается. Разрешение во время выполнения
соответствующая функция для вызова называется динамическим связыванием (по умолчанию
функции разрешаются статически во время компиляции). В C ++ динамический
привязка поддерживается с помощью механизма, называемого виртуальным классом
функции. Подтип полиморфизма через наследование и динамику
переплет обеспечивает основу для запрограммированного программирования
Основным преимуществом иерархии наследования является то, что мы можем программировать
к общедоступному интерфейсу абстрактного базового класса, а не к
отдельные типы, которые формируют его иерархию наследования, таким образом
экранирование нашего кода от изменений в этой иерархии. Определяем eval (),
например, как общедоступная виртуальная функция абстрактной базы запросов
учебный класс. Написание кода, такого как
_rop->eval();
Пользовательский код защищен от разнообразия и изменчивости нашего языка запросов. Это не только позволяет для добавления, пересмотра,
или удаление типов без необходимости изменения пользовательских программ, но
освобождает поставщика нового типа запроса от необходимости перекодировать поведение
или действия, общие для всех типов в самой иерархии. Это
поддерживаются две особые характеристики наследования: полиморфизм
и динамическое связывание. Когда мы говорим о полиморфизме в C ++, мы
в первую очередь означает способность указателя или ссылку на базовый класс
обратиться к любому из его производных классов. Например, если мы определим
не являющаяся членом функции eval () следующим образом, // pquery может обращаться к любому из
классы, полученные из Query
void eval( const Query *pquery ) { pquery->eval(); }
мы можем вызвать его легально, передавая адрес объекта любого из
четыре типа запросов:
int main()
{
AndQuery aq;
NotQuery notq;
OrQuery *oq = new OrQuery;
NameQuery nq( "Botticelli" ); // ok: each is derived from Query
// compiler converts to base class automatically
eval( &aq );
eval( ¬q );
eval( oq );
eval( &nq );
}
тогда как попытка вызвать eval () с адресом объекта, не полученного из Query
приводит к ошибке времени компиляции:
int main()
{ string name("Scooby-Doo" ); // error: string is not derived from Query
eval( &name);
}
Внутри eval () выполнение pquery-> eval (); должен ссылаться на
соответствующая виртуальная функция-член eval (), основанная на фактическом классе
адреса объектных запросов. В предыдущем примере pquery по очереди
обращается к объекту AndQuery, объекту NotQuery, объекту OrQuery,
и объект NameQuery. В каждой точке вызова во время выполнения
нашей программы, фактический тип класса, к которому обращается pquery
определяется и вызывается соответствующий экземпляр eval (). динамический
привязка - это механизм, с помощью которого это достигается.
В объектно-ориентированной парадигме программист манипулирует неизвестным экземпляром связанного, но бесконечного набора типов. (Набор
Типы связаны его иерархией наследования. В теории, однако, есть
нет предела глубине и ширине этой иерархии.) В C ++ это
достигается путем манипулирования объектами через базовый класс
только указатели и ссылки. В объектно-ориентированной парадигме
программистманипулирует экземпляром фиксированного единственного типа, который полностью определен в точке компиляции.Хотя полиморфное манипулирование объектом требует доступа к объекту либо через указатель, либо через ссылку, манипулирование указателем или ссылкой в C ++ само по себе не обязательно приводит к полиморфизму.Например, рассмотрим
// no polymorphism
int *pi;
// no language-supported polymorphism
void *pvi;
// ok: pquery may address any Query derivation
Query *pquery;
В C ++ полиморфизм существует только в отдельных иерархиях классов.Указатели типа void * могут быть описаны как полиморфные, но они не имеют явной поддержки языка - то есть они должны управляться программистом посредством явных приведений и некоторой формы дискриминанта, которая отслеживает фактический адресуемый тип.