Что именно это означает, если функция определена как виртуальная, и это то же самое, что и чисто виртуальная?
Из Виртуальной функции Википедии ...
В объектно-ориентированном программировании в таких языках, как C ++ и Object Pascal, виртуальная функция или виртуальный метод - это наследуемая и переопределяемая функция или метод, для которых облегчается динамическая диспетчеризация. Эта концепция является важной частью (полиморфизма во время выполнения) части объектно-ориентированного программирования (ООП). Короче говоря, виртуальная функция определяет целевую функцию, которая будет выполняться, но цель может быть неизвестна во время компиляции.
В отличие от не виртуальной функции, когда виртуальная функция переопределяется, наиболее производная версия используется на всех уровнях иерархии классов, а не только на уровне, на котором она была создана. Следовательно, если один метод базового класса вызывает виртуальный метод, версия, определенная в производном классе, будет использоваться вместо версии, определенной в базовом классе.
Это в отличие от не виртуальных функций, которые все еще могут быть переопределены в производном классе, но «новая» версия будет использоваться только производным классом и ниже, но не изменит функциональность базового класса вообще.
в то время как..
Чистая виртуальная функция или чисто виртуальный метод - это виртуальная функция, которая должна быть реализована производным классом, если производный класс не является абстрактным.
Когда существует чисто виртуальный метод, класс является «абстрактным» и не может быть создан самостоятельно. Вместо этого должен использоваться производный класс, который реализует чисто виртуальный метод (ы). Чисто виртуальный вообще не определен в базовом классе, поэтому производный класс должен его определять, или этот производный класс также является абстрактным и не может быть создан. Только класс, который не имеет абстрактных методов, может быть создан.
Виртуальный предоставляет способ переопределить функциональность базового класса, а чисто виртуальный требует этого.
pure
ключевое слово, но Bell Labs собиралась выпустить крупную версию C ++, и его менеджер не допустил бы этого на этой поздней стадии. Добавление ключевых слов это большое дело.Я хотел бы прокомментировать определение виртуального Википедии, как повторяется здесь. [На момент написания этого ответа] Википедия определила виртуальный метод как метод, который можно переопределить в подклассах. [К счастью, с тех пор Википедия была отредактирована, и теперь она объясняет это правильно.] Это неверно: любой метод, не только виртуальный, может быть переопределен в подклассах. Что делает виртуальный, так это дает вам полиморфизм, то есть способность выбирать во время выполнения наиболее производное переопределение метода .
Рассмотрим следующий код:
Каков вывод этой программы?
Производный переопределяет каждый метод Base: не только виртуальный, но и не виртуальный.
Мы видим, что когда у вас есть Base-pointer-to-Derived (bDerived), вызов NonVirtual вызывает реализацию базового класса. Это решается во время компиляции: компилятор видит, что bDerived - это Base *, что NonVirtual не является виртуальным, поэтому он выполняет разрешение для класса Base.
Однако вызов Virtual вызывает реализацию класса Derived. Из-за ключевого слова virtual выбор метода происходит во время выполнения , а не во время компиляции. Во время компиляции происходит то, что компилятор видит, что это Base *, и что он вызывает виртуальный метод, поэтому он вставляет вызов vtable вместо класса Base. Этот vtable создается во время выполнения, следовательно, разрешение во время выполнения переопределяется по большинству производных.
Надеюсь, это не слишком запутанно. Короче говоря, любой метод может быть переопределен, но только виртуальные методы дают вам полиморфизм, то есть выбор во время выполнения наиболее производного переопределения. На практике, однако, переопределение не виртуального метода считается плохой практикой и используется редко, поэтому многие люди (включая тех, кто написал эту статью в Википедии) считают, что только виртуальные методы могут быть переопределены.
источник
Derived*
с теми же вызовами функций, чтобы увести точку домой. В противном случае отличный ответКлючевое слово virtual дает C ++ возможность поддерживать полиморфизм. Когда у вас есть указатель на объект некоторого класса, такой как:
В этом (глупом) примере функция GetNumberOfLegs () возвращает соответствующее число на основе класса объекта, для которого она вызывается.
Теперь рассмотрим функцию SomeFunction. Неважно, какой тип животного объекта передается ему, если он получен из Animal. Компилятор автоматически преобразует любой производный от Animal класс в Animal, поскольку он является базовым классом.
Если мы сделаем это:
это вывело бы '2'. Если мы сделаем это:
это вывело бы '4'. Мы не можем сделать это:
потому что он не будет компилироваться из-за того, что виртуальная функция GetNumberOfLegs () является чистой, что означает, что она должна быть реализована путем получения классов (подклассов).
Чистые виртуальные функции в основном используются для определения:
а) абстрактные классы
Это базовые классы, где вы должны извлечь их, а затем реализовать чисто виртуальные функции.
б) интерфейсы
Это «пустые» классы, где все функции являются чисто виртуальными, и, следовательно, вы должны получить и затем реализовать все функции.
источник
В классе C ++, virtual - это ключевое слово, которое обозначает, что метод может быть переопределен (т.е. реализован) подклассом. Например:
В этом случае подкласс может переопределить функцию initShape для выполнения некоторой специализированной работы:
Термин « чисто виртуальный» относится к виртуальным функциям, которые должны быть реализованы подклассом и не были реализованы базовым классом. Вы определяете метод как чисто виртуальный, используя ключевое слово virtual и добавляя = 0 в конце объявления метода.
Итак, если вы хотите сделать Shape :: initShape чисто виртуальным, вы должны сделать следующее:
Добавляя чистый виртуальный метод в ваш класс, вы делаете класс абстрактным базовым классом, который очень удобен для отделения интерфейсов от реализации.
источник
m_name
. Чтоm_
значит?«Виртуальный» означает, что метод может быть переопределен в подклассах, но имеет непосредственную реализацию в базовом классе. «Чистый виртуальный» означает, что это виртуальный метод без прямой реализации. Такой метод должен быть переопределен хотя бы один раз в иерархии наследования - если у класса есть какие-либо нереализованные виртуальные методы, объекты этого класса не могут быть созданы, и компиляция завершится неудачно.
@quark указывает, что чисто виртуальные методы могут иметь реализацию, но поскольку чисто виртуальные методы должны быть переопределены, реализация по умолчанию не может быть вызвана напрямую. Вот пример чисто виртуального метода по умолчанию:
Согласно комментариям, неудача компиляции зависит от компилятора. По крайней мере, в GCC 4.3.3 он не будет компилироваться:
Вывод:
источник
Как работает виртуальное ключевое слово?
Предположим, что человек является базовым классом, индиец происходит от человека.
Объявление do_work () как виртуального просто означает, что do_work () для вызова будет определено ТОЛЬКО во время выполнения.
Предположим, я делаю,
Если virtual не используется, то же самое статически определяется или статически связывается компилятором, в зависимости от того, какой объект вызывается. Так что если объект Man вызывает do_work (), то do_work () Man называется ДАЖЕ, ЧТО ЭТО УКАЗЫВАЕТ НА ИНДИЙСКИЙ ОБЪЕКТ
Я считаю, что ответ с наибольшим количеством голосов вводит в заблуждение - любой метод, виртуальный или нет, может иметь переопределенную реализацию в производном классе. При конкретной ссылке на C ++ правильной разницей является привязка времени выполнения (когда используется виртуальная) и время компиляции (когда виртуальная не используется, но метод переопределен, а базовый указатель указывает на производный объект), привязка связанных функций.
Кажется, есть еще один вводящий в заблуждение комментарий, который гласит:
ЭТО НЕ ВЕРНО! Чисто виртуальные функции также могут иметь тело и могут быть реализованы! Правда в том, что чисто виртуальную функцию абстрактного класса можно вызывать статически! Два очень хороших автора - Бьярн Страуструп и Стэн Липпман ... потому что они написали язык.
источник
Виртуальная функция - это функция-член, которая объявлена в базовом классе и переопределена производным классом. Виртуальные функции являются иерархическими в порядке наследования. Когда производный класс не переопределяет виртуальную функцию, используется функция, определенная в его базовом классе.
Чистая виртуальная функция - это та, которая не содержит определения относительно базового класса. У него нет реализации в базовом классе. Любой производный класс должен переопределить эту функцию.
источник
Simula, C ++ и C #, которые по умолчанию используют статическое связывание методов, программист может указать, что конкретные методы должны использовать динамическое связывание, пометив их как виртуальные. Динамическое связывание методов является центральным в объектно-ориентированном программировании.
Объектно-ориентированное программирование требует трех основных понятий: инкапсуляция, наследование и динамическое связывание методов.
источник
Виртуальные методы МОГУТ быть переопределены производными классами, но нуждаются в реализации в базовом классе (тот, который будет переопределен)
Чистые виртуальные методы не имеют реализации базового класса. Они должны быть определены производными классами. (Так что технически переопределено не правильный термин, потому что нечего переопределять).
Virtual соответствует стандартному поведению Java, когда производный класс переопределяет метод базового класса.
Чисто виртуальные методы соответствуют поведению абстрактных методов внутри абстрактных классов. И класс, который содержит только чистые виртуальные методы и константы, будет cpp-pendant для интерфейса.
источник
Чистая виртуальная функция
попробуй этот код
В классе anotherClass удалите функцию sayHellow и запустите код. вы получите ошибку! Потому что, когда класс содержит чисто виртуальную функцию, из этого класса невозможно создать объект, и он наследуется, тогда его производный класс должен реализовать эту функцию.
Виртуальная функция
попробуй другой код
Здесь функция sayHellow помечена как виртуальная в базовом классе. Это говорит о компиляторе, который пытается найти функцию в производном классе и реализовать функцию. Если она не найдена, выполнить базовую. Спасибо
источник
«Виртуальная функция или виртуальный метод - это функция или метод, поведение которых может быть переопределено в наследующем классе функцией с такой же сигнатурой» - википедия
Это не очень хорошее объяснение для виртуальных функций. Потому что, даже если член не является виртуальным, наследующие классы могут переопределить его. Вы можете попробовать и увидеть это сами.
Разница проявляется, когда функция принимает базовый класс в качестве параметра. Когда вы задаете наследующий класс в качестве входных данных, эта функция использует реализацию переопределенной функции базового класса. Однако, если эта функция является виртуальной, она использует ту, которая реализована в производном классе.
источник
Виртуальные функции должны иметь определение в базовом классе, а также в производном классе, но не обязательно, например, функция ToString () или toString () является виртуальной, чтобы вы могли предоставить собственную реализацию, переопределив ее в определяемом пользователем классе (ах).
Виртуальные функции объявлены и определены в обычном классе.
Чистая виртуальная функция должна быть объявлена с окончанием "= 0", и она может быть объявлена только в абстрактном классе.
Абстрактный класс, имеющий чисто виртуальную функцию (и), не может иметь определения (ей) этих чисто виртуальных функций, поэтому он подразумевает, что реализация должна быть обеспечена в классе (ах), который получен из этого абстрактного класса.
источник