7.2.8 Виртуальные Функции

7.2.8 Виртуальные Функции

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

struct employee (* employee* next; char* name; short department; // ... virtual void print(); *);

Ключевое слово virtual указывает, что могут быть разлиные варианты функции print() для разных производных классов, и что поиск среди них подходящей для каждого вызова print() является задачей компилятора. Тип функции описывается в базвом классе и не может переописываться в производном классе. Виртуальная функция должна быть определена для класса, в ктором она описана впервые. Например:

void employee::print() (* cout «„ e-“name „„ „ “ «« e-“department «« « “; // ... *)

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

struct manager : employee (* employee* group; short level; // ... void print(); *);

void manager::print() (* employee::print(); cout «„ „ уровень“ «« level «« « “; // ... *)

Функция print_employee() теперь не нужна, поскольку ее место заняли функции члены print(), и теперь со списком слжащих можно работать так:

void f(employee* ll) (* for (; ll; ll=ll-»next) ll-»print(); *)

Каждый служащий будет печататься в соответствии с его типом. Например:

main() (* employee e; e.name = «Дж.Браун»; e.department = 1234; e.next = 0; manager m; m.name = «Дж.Смит»; e.department = 1234; m.level = 2; m.next = amp;e; f( amp;m); *)

выдаст

Дж.Смит 1234 уровень 2 Дж.Браун 1234

Заметьте, что это будет работать даже в том случае, если f() была написана и откомпилирована еще до того, как проиводный класс manager был задуман! Очевидно, при реализации этого в каждом объекте класса employee сохраняется некоторая информация о типе. Занимаемого для этого пространства (в ткущей реализации) как раз хватает для хранения указателя. Это пространство занимается только в объектах классов с виртуалными функциями, а не во всех объектах классов и даже не во

всех объектах производных классов. Вы платите эту пошлину только за те классы, для которых описали виртуальные функции.

Вызов функции с помощью операции разрешения области вдимости ::, как это делается в manager::print(), гарантирует, что механизм виртуальных функций применяться не будет. Иначе manager::print() подвергалось бы бесконечной рекурсии. Примнение уточненного имени имеет еще один эффект, который может оказаться полезным: если описанная как virtual функция описна еще и как inline (в чем ничего необычного нет), то там, где в вызове применяется ::, может применяться inline-подстновка. Это дает программисту эффективный способ справляться с теми важными специальными случаями, когда одна виртуальная функция вызывает другую для того же объекта. Поскольку тип объекта был определен при вызове первой виртуальной функции, обычно его не надо снова динамически определять другом вызове для того же объекта.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

1.18 Виртуальные Функции

Из книги C++ автора Хилл Мюррей

1.18 Виртуальные Функции Предположим, что мы пишем программу для изображения фигур на экране. Общие атрибуты фигуры представлены классом shape, а специальные атрибуты – специальными классами:class shape (* point center; color col; //... public: void move(point to) (* center=to; draw(); *) point where() (* return center; *) virtual void


7.2.8 Виртуальные Функции

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

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


8.5.4 Виртуальные Функции

Из книги Популярный самоучитель работы в Интернете автора Кондратьев Геннадий Геннадьевич

8.5.4 Виртуальные Функции Если базовый класс base содержит virtual (виртуальную) (#8.1) функцию vf, а производный класс derived также содержит функцию vf, то обе функции должны иметь один и тот же тип, и вызов vf для объекта класса derived вызывает derived::vf. Например:struct base (* virtual void vf (); void f (); *);class


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

Из книги Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ автора Мейерс Скотт


Виртуальные покупки

Из книги Новейший самоучитель работы на компьютере автора Белунцов Валерий

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


Правило 9: Никогда не вызывайте виртуальные функции в конструкторе или деструкторе

Из книги Scrum и XP: заметки с передовой автора Книберг Хенрик

Правило 9: Никогда не вызывайте виртуальные функции в конструкторе или деструкторе Начну с повторения: вы не должны вызывать виртуальные функции во время работы конструкторов или деструкторов, потому что эти вызовы будут делать не то, что вы думаете, и результатами их


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

Из книги Описание работы пакета OOoFBTools Создание книг FB2 автора Кузнецов Вадим

Виртуальные открытки В последнее время довольно популярными стали службы, позволяющие посылать по почте виртуальные открытки, например поздравительные (рис. 19.12). Рис. 19.12. Пример виртуальной открытки.Вкратце данный процесс можно описать так. Пользователь отправляется


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

Из книги Стандарты программирования на С++. 101 правило и рекомендация автора Александреску Андрей


IV. Виртуальные клавиатуры

Из книги Видеосамоучитель создания реферата, курсовой, диплома на компьютере автора Баловсяк Надежда Васильевна

IV. Виртуальные клавиатуры IV.1. Виды виртуальных клавиатурИногда требуется в текст документа (корректура, правка после OCR) ввести Unicode символы. Удобнее для этого использовать соответствующие виртуальные клавиатуры:1. Различные символы (стрелки, ноты…): 2. Математическая: 3.


39. Виртуальные функции стоит делать неоткрытыми, а открытые — невиртуальными

Из книги C++ для начинающих автора Липпман Стенли

39. Виртуальные функции стоит делать неоткрытыми, а открытые — невиртуальными РезюмеВ базовых классах с высокой стоимостью изменений (в частности, в библиотеках) лучше делать открытые функции невиртуальными. Виртуальные функции лучше делать закрытыми, или защищенными —


10.2. Виртуальные библиотеки

Из книги автора

10.2. Виртуальные библиотеки Интернет, являющийся гигантским хранилищем всевозможных сведений, представляет собой уникальный источник информации. Наряду с другими, библиографические ресурсы Сети помогут в поиске необходимой информации. Они представлены, прежде всего,


17.5. Виртуальные функции в базовом и производном классах

Из книги автора

17.5. Виртуальные функции в базовом и производном классах По умолчанию функции-члены класса не являются виртуальными. В подобных случаях при обращении вызывается функция, определенная в статическом типе объекта класса (или указателя, или ссылки на объект), для которого она


17.5.4. Виртуальные функции и аргументы по умолчанию

Из книги автора

17.5.4. Виртуальные функции и аргументы по умолчанию Рассмотрим следующую простую иерархию классов:#include iostreamclass base {public:virtual int foo( int ival = 1024 ) {cout " base::foo() -- ival: " ival endl;return ival;}// ...};class derived : public base {public:virtual int foo( int ival = 2048 ) {cout " derived::foo() -- ival: " ival endl;return ival;}// ...};Проектировщик


17.5.5. Виртуальные деструкторы

Из книги автора

17.5.5. Виртуальные деструкторы В данной функции мы применяем оператор delete:void doit_and_bedone( vector Query* *pvec ){// ...for ( ; it != end_it; ++it ){Query *pq = *it;// ...delete pq;}}Чтобы функция выполнялась правильно, применение delete должно вызывать деструктор того класса, на который указывает pq. Следовательно,


17.5.8. Виртуальные функции, конструкторы и деструкторы

Из книги автора

17.5.8. Виртуальные функции, конструкторы и деструкторы Как мы видели в разделе 17.4, для объекта производного класса сначала вызывается конструктор базового, а затем производного класса. Например, при таком определении объекта NameQueryNameQuery poet( "Orlen" );сначала будет вызван


19.2.4. Объекты-исключения и виртуальные функции

Из книги автора

19.2.4. Объекты-исключения и виртуальные функции Если сгенерированный объект-исключение имеет тип производного класса, а обрабатывается catch-обработчиком для базового, то этот обработчик не может использовать особенности производного класса. Например, к функции-члену value(),