Рубрика «виртуальные функции»

Привет. Если ты знаешь ответ на вопрос в заголовке, – поздравляю, эта статья тебе не нужна. Она адресуется новичкам в программировании, вроде меня, которые не всегда могут самостоятельно разобраться со всеми тонкостями C++ и других типизированных языков, а если и могут, лучше всё равно учиться на чужих ошибках.
В данной статье я не просто отвечу на вопрос "Зачем нужны виртуальные функции в C++", а приведу пример из своей практики. Для краткого ответа можно обратиться к поисковикам, которые выдают примерно следующее: "Виртуальные функции нужны для обеспечения полиморфизма — одного из трёх китов ООП. Благодаря им машина может сама определить тип объекта по указателю, не загружая этой задачей программиста". О'кей, но вопрос «зачем» остался, хотя теперь он значит немного другое: "Зачем полагаться на машину, тратить лишние время и память, если можно самостоятельно подкастовать указатель, ведь тип объекта, на который он ссылается, почти всегда известен?" Действительно, кастование на первый взгляд оставляет виртуальные функции без работы, и именно оно становится причиной заблуждений и плохого кода. В мелких проектах проигрыш незаметен, но, как вы скоро убедитесь, с ростом программы касты увеличивают листинг в почти геометрической прогрессии.
Читать полностью »

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

  • Регистры и их назначение при вызове функций.
  • Передача и возврат простых типов и структур.
  • Как передача по ссылке и по значению влияют на оптимизации тела функции компилятором.
  • Как используется место при многочисленных вызовах функций.
  • Механизм виртуальных вызовов.
  • Оптимизация хвостовых вызовов и рекурсии.
  • Инициализация структур, массивов и векторов.

Осторожно! Статья содержит большое количество кода на C++ и ассемблере (с комментариями), а также множество таблиц с оценками производительности.

Читать полностью »

Некоторое время назад ко мне подошли программисты, недавно начавшие изучать с++ и привыкшие к процедурному программированию, с жалобой на то, что механизм вызова виртуальных методов «тормозит». Я был очень удивлён.

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

Итого имеем следующие дополнительные затраты:

1) Дополнительный указатель в классе (указатель на таблицу виртуальных методов);
2) Дополнительный код в конструкторе класса (для инициализации виртуального табличного указателя);
3) Дополнительный код при каждом вызове виртуального метода (разыменование указателя на таблицу виртуальных методов и поиск по таблице нужного адреса виртуального метода).
Читать полностью »

Недавно мне задали вопрос: как бы я реализовал механизм виртуальных функций на языке C?

Поначалу я понятия не имел, как это можно сделать: ведь C не является языком объектно-ориентированного программирования, и здесь нет такого понятия, как наследование. Но поскольку у меня уже было немного опыта с C, и я знал, как работают виртуальные функции, я подумал, что должен быть способ сымитировать поведение виртуальных функций, используя структуры (struct).

Краткое пояснение для тех, кто не знает, что такое виртуальные функции:
Виртуальная функция — это функция, которая может быть переопределена классом-наследником, для того чтобы тотЧитать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js