Динамическое связывание в C ++ - PullRequest
3 голосов
/ 23 июня 2009

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

Ответы [ 5 ]

5 голосов
/ 23 июня 2009

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

3 голосов
/ 23 июня 2009

Это не так.

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

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

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

2 голосов
/ 23 июня 2009

Цитировать стандарт C ++ (10.3.2):

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

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

2 голосов
/ 23 июня 2009

Это так? Следующий код производит ожидаемый вывод 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;
}
0 голосов
/ 23 июня 2009

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

...