class BaseКласс Derived переопределяет метод
{
public:
virtual void Do() { cout << "Base::Do()" << endl; }
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual void Do() { cout << "Derived::Do()" << endl; }
};
Do()
, и код, оперирующий объектом этого класса, при вызове Do()
будет всегда вызвать Base::Do()
.Даже если преобразовать указатель или ссылку на объект класса Derived к указателю или ссылке на Base, то будет вызываться
Derived::Do()
- за это отвечает таблица виртуальных функций или другой подобный механизм, встроенный в язык:Derived d;
d.Do(); // Derived::Do()
Base& b = d;
b.Do(); // тоже Derived::Do()
А теперь вопрос: как вызвать
Base::Do()
для объекта типа Derived?Во-первых, разберемся корректно ли это. По сути,
void Base::Do()
представляет собой void Do(Base* This)
, а void Derived::Do()
представляет void Do(Derived* This)
. Так как можно легко преобразовывать Derived*
к Base*
, то есть вызов Base::Do()
для Derived является корректным. Такой вызов часто используется при напимании методов унаследанного класса:void Derived::DoSomething()Прекрасно, "изнутри" Derived (то есть из методов самого Derived) мы можем вызывать
{
// do something
Base::Do();
// do something else
}
Base::Do()
, но как быть если нужно вызвать этот метод "снаружи"?Оказывается, синтаксис такой:
Derived d;
d.Base::Do();