На роботу в Яндекс
Листопад 7th, 2008
Виявляється, Яндекс постійно набирає нових людей, зокрема, розробників C++. Перша частина співбесіди — онлайн. Завдання, що там пропонуються, без сумніву, варті уваги. Ось , наприклад, таке
-
-
class Top {
-
public:
-
virtual ~Top (){}
-
};
-
-
class Right : virtual public Top {
-
public:
-
void f () {}
-
};
-
-
class Left : virtual public Top {
-
public:
-
void f () {}
-
};
-
-
class Bottom : public Right, public Left {
-
public:
-
/*
-
* что надо написать чтобы выполнялось требование описанное в main
-
*/
-
};
-
-
int main (int, char**) {
-
Bottom b;
-
b.f(); // Требование: вызов Left::f()
-
}
-
Звісно, перше, що спадає на думку, зробити шось типу
void f () { Left::f();}
Але так негарно. Виклик однієї функції через іншу… Не дуже добре, особливо якщо в реальному житті трапиться метод з багатьма параметрами.
Насправді, розумні люди підказали , треба робити так:
using Left::f;
Цей запис виглядав би так само, навіть якби у батьківських класах метод f приймав би якісь параметри.
В тому коді є ще пара цікавих моменти, про які особисто я не знав, не знав, та й забув.
По-перше, спосіб наслідування virtual publiс. Виявляється, слово virtual в даному випадку означає, що у класі Bottom буде присутня одна і тільки одна реалізація об’єкту класу Top. Якби virtual не було, тоді виникала б неоднозначність при використанні членів класу Top, успадкованих як в Left, так і в Right. Втім, в прикладі цього не видно, бо в Top занадто спрощений.
По-друге, клас Top має віртуальний деструктор. Питання: який взагалі сенс деструктору бути віртуальним, коли його все одно не можна перекрити в класі-нащадку? Погугливши, знайшов відповідь . Справа в тому, що якби не слово virtual, то ось в такому випадку
int main {
Top* tp = new Right;
}
було б викликано деструктор явно заданого класу (Top), в той час, коли насправді треба викликати ~Right.




