Я правильно понимаю, что ключевое слово virtual используется в тех
случаях, когда в дочернем классе мы переопределяем метод предка и при
этом при вызове:
BaseClass a;
a = new DerivedClass();
a.some();
мы хотим вызывать функцию дочернего класса.
Просто, если я не ошибаюсь, во всех остальных языках программирования
это станждартное поведение — Python, Ruby, кажется, Java. Все методы по
умолчанию ведут себя как виртуальные.
А зачем в C++ понадобилось вводить дополнительное ключевое слово virtual ?
Здравствуйте, DemAS, Вы писали:
DAS>Просто, если я не ошибаюсь, во всех остальных языках программирования DAS>это станждартное поведение — Python, Ruby, кажется, Java. Все методы по DAS>умолчанию ведут себя как виртуальные.
Только в том случае, если "все остальные языки программирования" это вышеперечисленные.
DAS>А зачем в C++ понадобилось вводить дополнительное ключевое слово virtual ?
Здравствуйте, DemAS, Вы писали:
DAS>Просто, если я не ошибаюсь, во всех остальных языках программирования DAS>это станждартное поведение — Python, Ruby, кажется, Java. Все методы по DAS>умолчанию ведут себя как виртуальные.
DAS>А зачем в C++ понадобилось вводить дополнительное ключевое слово virtual ?
Здравствуйте, DemAS, Вы писали:
DAS>А зачем в C++ понадобилось вводить дополнительное ключевое слово virtual ?
Вызов виртуального метода немного дороже, чем невиртуального. Кроме того, если метод не виртуален, то компилятор в точке вызова точно знает, что будет вызвано, а поэтому может заглянуть внутрь и использовать увиденное там для оптимизации (например, подставить функцию inline, или не вычислять какой-то параметр, который в вызываемом методе все равно не используется, ну и т.п.).
На фоне накладных расходов питона и т.п. такие дополнительные издержки не очень заметны, а вот на фоне c++ могут быть и заметны.
Здравствуйте, DemAS, Вы писали:
DAS>А зачем в C++ понадобилось вводить дополнительное ключевое слово virtual ?
Что-бы была возможность сделать не виртуальную функцию, так как не виртуальные функции вызываются быстрее (не надо искать по таблице виртуальных функций).
Здравствуйте, ankorol, Вы писали:
A>Что-бы была возможность сделать не виртуальную функцию, так как не виртуальные функции вызываются быстрее (не надо искать по таблице виртуальных функций).
И можно сделать inline подстановку...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, jazzer, Вы писали:
J>>Они все немножко того... После С++ появились...
К>Smalltalk немножко того, раньше С++ появился...
Smalltalk за пределами ксерокса появился в 80-м, а С++ Бьярне начал разрабатывать в 79-м, под влиянием Симулы, в которой виртуальные функции объявлялись явно, как раз с использованием слова Virtual: http://en.wikipedia.org/wiki/Simula#Classes.2C_subclasses_and_virtual_methods
И оттуда же, кстати, идет мода не объявлять явно виртуальными перекрытые виртуальные функции.
А Симула появилась в 67-м (Смолтолк только начали разрабатывать в 69).
ЗЫ посмотрел статью про симулу в википедии, сразу такая ностальгия по алголу, хоть я на нем своими руками и не писал...
J>Они все немножко того... После С++ появились...
Дело не в том, я думаю. Виртуальный вызов дороже, следовательно, если есть возможность сэкономить — отчего бы и не сэкономить?
Здравствуйте, Vamp, Вы писали:
J>>Они все немножко того... После С++ появились... V>Дело не в том, я думаю. Виртуальный вызов дороже, следовательно, если есть возможность сэкономить — отчего бы и не сэкономить?
Понятно, что не в том, просто сравнение некорректное — вопрос ставился так, будто все означенные языки существовали на момент создания С++, и С++ пошел поперек сложившейся традиции.
А основные аргументы — это, в первую очередь, совместимость с С.
Ведь если у тебя есть виртуальные функции, то должен быть и vtbl, а в объекте должен лежать указатель на него, так что одна и та же структура, объявленная в С и в С++, будет уже несовместимой.
Плюс этот vtbl придется все время таскать с собой, даже в случае простейших оберточных классов типа struct Int { int v; };
Ну и скорость виртуальных вызовов в то время была очень плохой, это уже потом компиляторы стали специально затачивать под скорость выполнения именно виртуальных вызовов (т.е чтоб vtbl всегда был под рукой, чтоб статические вызовы через таблицу не ходили, и т.п.).
Примерно как сейчас, когда народ ударился в шаблонное метапрограммирование, и компиляторы оказались к нему совершенно не готовы (потому что изначально никаких применений шаблонов, кроме всяких тривиальных контейнеров с одним, максимум двумя типовыми аргументами, и максимум парой генерящихся классов на одно инстанцирование шаблона, не было), и все теперь думают, что же надо в компиляторах менять, чтоб вся эта куча шаблонов, которая инстанцируется при использовании какого-нть метакласса, быстро компилировалась.
J>А основные аргументы — это, в первую очередь, совместимость с С.
Аргумент сомнительный. В С и ключевого слова class нету. Не нужна там совместимость.
J>Ведь если у тебя есть виртуальные функции, то должен быть и vtbl, а в объекте должен лежать указатель на него...
Тоже не вполне правильное утверждение. vtbl — это просто один из способов реализации виртуальных функций. Можно и без нее.
J>Плюс этот vtbl придется все время таскать с собой, даже в случае простейших оберточных классов типа struct Int { int v; };
Эту. В японском родов нету, что ли?
J>теперь думают, что же надо в компиляторах менять, чтоб вся эта куча шаблонов, которая инстанцируется при использовании какого-нть метакласса, быстро компилировалась.
Компиляторы надо менять. Шаблонные извращения вроде enable_if или того же lambda — кошмар и ужас.