Динамическое связывание в 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 в функциях производного класса, так как это сделает динамическое связывание, связанное с этими функциями, более четким при чтении кода.