28 сентября 2006

Calling base class virtual method

Предположим, у нас есть иерархия классов:
class Base
{
public:
virtual void Do() { cout << "Base::Do()" << endl; }
virtual ~Base() {}
};

class Derived : public Base
{
public:
virtual void Do() { cout << "Derived::Do()" << endl; }
};
Класс Derived переопределяет метод 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()
{
// do something
Base::Do();
// do something else
}
Прекрасно, "изнутри" Derived (то есть из методов самого Derived) мы можем вызывать Base::Do(), но как быть если нужно вызвать этот метод "снаружи"?

Оказывается, синтаксис такой:
Derived d;
d.Base::Do();

Комментариев нет: