Использование виртуального ключевого слова в С++

Я понимаю, что С++ реализует виртуальные функции полиморфизма времени выполнения и что виртуальное ключевое слово наследуется, но я не вижу использования виртуального ключевого слова в производном классе.

например. В нижеприведенном случае, даже если вы уронили виртуальное ключевое слово в производном классе, вызов ptr- > method() перейдет к методу output::. Итак, какое дополнительное виртуальное ключевое слово выполняет в производном классе?

#include<iostream>

using namespace std;

class base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "BASE" << std::endl;
    }
};

class derived: public base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED" << std::endl;
    }
};

int main()
{
    base* ptr = new derived();
    ptr->method();
    return 9;
}

Ответ 1

Ничего. Просто чтобы напомнить вам, какие функции виртуальны или нет.

Ответ 2

Если метод производного класса соответствует виртуальному методу одного из базовых классов по имени и сигнатуре, а соответствующий метод является виртуальным, то метод производного класса также становится виртуальным. Таким образом, технически нет необходимости отмечать такие методы, как "virtual" в производных классах. Тем не менее, перед С++ 11 это была хорошая практика только потому, что это отличный намек на тех, кто читает код (было бы сложно учесть все виртуальные функции базового класса (ов)).

Начиная с С++ 11, для производных классов есть два дополнительных ключевых слова, которые помогают как удобочитаемости, так и надежности кода. Они "переопределяют" и "окончательные". Например, установка "override" в методе производного класса гарантирует, что соответствующий метод базового класса фактически является виртуальным. Ключевое слово "final" делает то же самое, что и препятствует дальнейшему переопределению метода.

Я также писал об этом с более обоснованными примерами и примерами кода в моем блоге, здесь.

Надеюсь, это поможет. Удачи!

Ответ 3

virtual требуется только в объявлении базового класса. Он необязателен в производном классе (-ах) и, вероятно, служит в основном как напоминание в этих случаях.

С++ 11 вводит override, чтобы сделать вещи более явными: он явно помещает метод в производном классе как переопределение метода virtual базового класса.

Ответ 4

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

Пример:

В вашем коде мы добавляем этот код.

   class derived: public base {
    public:
        virtual void method() {    // In this line virtual keyword is optional.
              std::cout << std::endl << "DERIVED :: method function" << std::endl;
        }

        virtual void display() {
              std::cout << std::endl << "DERIVED :: display function" << std::endl;
        }
   };

   class deriveChild: public derived {
        public:
            void method() {
                 std::cout << std::endl << "DERIVECHILD :: method" << std::endl;
            }

        void display() {
                 std::cout << std::endl << "DERIVECHILD:: display" << std::endl;
            }
   };

В основном(), если вы используете код ниже, он даст вам другой результат.

   base  *ptr = new deriveChild();
   ptr->method(); // will compile and execute
   ptr->display(); // will generate error because display() is not part of base class.

Теперь, если вы хотите использовать display() класса deriveChild, используйте этот код.

   derived *ptr = new deriveChild();
   ptr->method(); // Compile and Execute 
   ptr->display(); // Compile and Execute

Ответ 5

Неявно виртуальные методы в производных классах являются виртуальными в производных классах, не нужно явно определять их virtual.If вы заявляете, что это будет избыточное объявление.

ptr->method();

Когда компилятор столкнулся с приведенным выше утверждением

- > Он попытается разрешить вышеупомянутый оператор, поскольку функция метода() является виртуальной, компилятор отложил разрешение этого вызова на время выполнения.

- > Когда вы создавали объект производного класса во время выполнения, теперь компилятор узнает, что этот метод имеет производный класс.

какое дополнительное виртуальное ключевое слово выполняет в производном классе?

Рассмотрим этот сценарий, есть еще один производный класс, называемый производной производной Derived2, и имеет свой собственный виртуальный метод.

 class derived2: public derived
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED2" << std::endl;
    }
};

Если вы вызываете метод() в главном, как показано ниже

int main()
{
    base* ptr = new derived2();
    ptr->method();   //derived2 class method() will get called
    return 9;
}

Если метод() в производном2 по умолчанию не является виртуальным, вы в конечном итоге вызываете производную версию метода(), теряя преимущество полиморфизма во время выполнения.

Следовательно, авторы С++ сделали здесь замечательную работу, сделав иерархическое наследование по иерархии ключевых слов.