Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Виртуальные методы, механизм позднего связывания.





Виртуальные методы

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

/ / Описывается указатель на базовый класс:

monstr *р;

/ / Указатель ссылается на объект производного класса:

р = new daemon:

Вызов методов объекта происходит в соответствии с типом указателя, а не фактическим типом объекта, на который он ссылается, поэтому при выполнении оператора, например,

p->draw(l. 1. 1. 1):

будет вызван метод класса monstr, а не класса daemon, поскольку ссылки на методы разрешаются во время компоновки программы. Этот процесс,называется ранним связыванием. Чтобы вызвать метод класса daemon, можно использовать явное преобразованиетипа указателя:

(daemon * p)->draw(l. 1. 1. 1);

Это не всегда возможно, поскольку в разное время указатель может ссылаться на объекты разных классов иерархии, и во время компиляции программы конкретный класс может быть неизвестен. В качестве примера можно привести функцию, параметром которой является указатель на объект базового класса. На его место во время выполнения программы может быть передан указатель на любой производный класс. Другой пример — связный список указателей па различные объекты иерархии, с которым требуется работать единообразно.

В C++ реализован механизм позднего связывания, когда разрешение ссылок на метод происходит на этапе выполнения программы в зависимости от конкретного типа объекта, вызвавшего метод. Этот механизм реализован с помощью виртуальных методов и рассмотрен в следующем разделе.

Для определения виртуального метода используется спецификатор virtual, например:

virtual void draw(int х. int у. int scale, int position);

Рассмотрим правила описания и использования виртуальных методов.

• Если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным, а с отличающимся набором параметров — обычным.

• Виртуальные методы наследуются, то есть переопределять их в производном классе требуется только при необходимости задать отличающиеся действия. Права доступа при переопределении изменить нельзя.

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

• Виртуальный метод не может объявляться с модификатором static, но может быть объявлен как дружественный.

• Если в классе вводится описание виртуального метода, он должен быть определен хотя бы как чисто виртуальный.

Чисто виртуальный метод содержит признак» О вместо тела, например:

virtual void f(int) = 0;

Чисто виртуальный метод должен переопределяться в производном классе (возможно, опять как чисто виртуальный). Если определить метод draw в классе raonstr как виртуальный, решение о том, метод какого класса вызвать, будет приниматься в зависимости от типа объекта, на который ссылается указатель:

monstr * г. *р;

г = new monstr;. // Создается объект класса monstr

р = new daemon; // Создается объект класса daemon

r->draw(l. 1. 1. 1); // Вызывается метод monstr::draw

p->draw(l. 1. 1. 1); // Вызывается метод daemon::draw

р-> monstr: rdrawd, 1. 1. 1); // Обход механизма виртуальных методов

Если объект класса daemon будет вызывать метод draw не непосредственно, а косвенно (то есть из другого метода, определенного в классе monstr), будет вызван метод draw класса daemon.

Итак, виртуальным называется методу ссылка на который разрешается на этапе выполнения программы (перевод красивого английского слова virtual — в данном значении всего-навсего «фактический», то есть ссылка разрешается по факту вызова).

class Ancestor

{

public:

virtual void function1 () { cout << "Ancestor::function1()" << endl; }

void function2 () { cout << "Ancestor::function2()" << endl; }

};

 

class Descendant: public Ancestor

{

public:

virtual void function1 () { cout << "Descendant::function1()" << endl; }

void function2 () { cout << "Descendant::function2()" << endl; }

};

 

Descendant* pointer = new Descendant ();

Ancestor* pointer_copy = pointer;

 

pointer->function1 ();

pointer->function2 ();

 

pointer_copy->function1 ();

pointer_copy->function2 ();

В этом примере класс Ancestor определяет две функции, одну из них виртуальную, другую — нет. Класс Descendant переопределяет обе функции. Однако, казалось бы одинаковое обращение к функциям даёт разные результаты. На выводе программа даст следующее:

Descendant::function1()

Descendant::function2()

Descendant::function1()

Ancestor::function2()

 







Date: 2016-07-25; view: 519; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию