Почему производный класс должен объявлять свои методы виртуальными для динамической привязки для работы, даже если методы базового класса объявлены виртуальными?Динамическое связывание в C++
ответ
Этого не нужно. Если метод объявлен виртуальным в базовом классе, переопределение его в производном классе также делает виртуальную функцию переопределения, даже если ключевое слово 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;
}
Спасибо за ваш ответ, много помогли. – user224579
Это не так.
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
к переопределяющим функциям-членам, чтобы дать пользователю понять, что класс является полиморфным.
Не нужно этого. Но я предпочитаю использовать виртуальные функции производного класса, так как это сделает динамическое связывание, связанное с этими функциями, более понятным при чтении кода.
Спасибо, я этого не знал. – user224579