Листопад 10th, 2008
Ще одне цікаве завдання, з тих, що пропонує Яндекс:
Есть класс CodeGenerator, который умеет генерить код на разных языках.
-
-
class CodeGenerator
-
{
-
public:
-
enum Lang {JAVA, C_PLUS_PLUS, PHP};
-
CodeGenerator(Lang language) { _language=language; }
-
std::string generateCode()
-
{
-
switch(_language) {
-
case JAVA: //return generated java code
-
case C_PLUS_PLUS: //return generated C++ code
-
case PHP: //return generated PHP code
-
}
-
throw new std::logic_error("Bad language");
-
}
-
std::string someCodeRelatedThing() // used in generateCode()
-
{
-
switch(_language) {
-
case JAVA: //return generated java-related stuff
-
case C_PLUS_PLUS: //return generated C++-related stuff
-
case PHP: //return generated PHP-related stuff
-
}
-
throw new std::logic_error("Bad language");
-
}
-
-
private:
-
Lang _language;
-
}
-
Исходя из предположения, что количество языков будет добавляться, предложите refactoring кода. Аргументируйте преимущество вашего кода над существующим.
(ще…)
Категорії: C/C++, Паттерни проектування |
Теґи:c/c++, factory, refactoring, yandex, паттерни програмування, програмування, рефакторінг | Кометарів немає
Листопад 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.
Категорії: C/C++ |
Теґи:c/c++, virtual, yandex, Яндекс | Кометарів немає