Динамическое связывание в C++

Почему производный класс должен объявлять свои методы как виртуальные, чтобы динамическая привязка работала, даже если методы базового класса объявлены виртуальными?

5 ответов

Решение

Это не обязательно. Если метод объявлен виртуальным в базовом классе, переопределение его в производном классе также делает виртуальную функцию переопределением, даже если virtual Ключевое слово не используется.

Это не так.

class Base
{
    virtual void foo() {}
};

class Derived : public Base
{
    void foo() {}
}

в этом коде foo() все еще виртуален в Derived класс, даже если он не объявлен как таковой.

Чтобы процитировать стандарт C++ (10.3.2):

Если функция виртуального члена vf объявлен в классе Base и в классе Derivedпрямо или косвенно Base, функция-член vf с тем же именем и тем же списком параметров, что и Base::vf объявлен, то Derived::vf также является виртуальным (независимо от того, объявлено оно или нет) и переопределяет Base::vf,

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

Это? Следующий код производит ожидаемый вывод B::f1() (скомпилированный с использованием VS2008):

class A
{
public:

    virtual ~A(){}
      virtual void f1()
      {
        std::cout<<"A::f1()\n";
      }

        virtual void f2()
      {
        std::cout<<"A::f2()\n";
      }
};

class B : public A
{
public:
       void f1()
      {
        std::cout<<"B::f1()\n";
      }

         void f2()
      {
        std::cout<<"B::f2()\n";
      }
};


int  main()
{
    B b;
    A* p = &b;
    p->f1();

    return 0;
}

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

Другие вопросы по тегам