Задачка по программированию
Давным-давно, когда я искал работу, мне прислали одну интересную задачку, которую я до сих пор гуглю на просторах интернета. Причем гуглю безответно — народ ломает голову, но ничего толкового придумать не может.
Я не самый большой специалист по С++, поэтому тешу себя мыслью, что если я ошибаюсь — меня поправят, а если нет — пусть статья выходит в топы гугла и висит там, дабы ее прекратили давать на собеседованиях. Потому что задача идиотская.
Звучит она так:
Перегрузка оператора присваивания
Пусть есть класс
class Boo : public SuperBoo
{
Foo* fFoo1;
Foo* fFoo2;
}
Где Foo – мономорфный класс, а класс Boo владеет указателями fFoo1, fFoo2.
Задача: перегрузить оператор присваивания для класса Boo.
Начнем с первого — с мономорфного класса. Все знают, что ООП состоит из полиморфизма, инкапсуляции и наследования. Определение полиморфизма можно прочитать в википедии, а пользуясь нехитрой логикой можно понять, что мономорфный — антоним понятия «полиморфный». Таким образом, в нашем случае, мономорфный класс — это класс, указатель на который всегда представляет его самого, а не его наследника.
То есть мы можем гарантировать то, что за Foo* скрывается класс Foo, а не какой-нибудь class MegaFoo : public Foo.
Второй вывод, который мы можем сделать из текста задачи — что класс Boo владеет указателями, а значит удаляет их в деструкторе. Таким образом, нам необходимо помнить о политике владения при написании оператора присваивания и четко удалять и создавать новые объекты.
Третий вывод позволяет нам сделать наличие суперкласса у Foo. Вполне возможно, что у SuperFoo есть оператор присвания, а значит нам необходимо его вызвать. Если же его нет — не беда, всегда есть оператор присваивания по умолчанию, просто копирующий блок памяти.
Таким образом, по нашему трезвому измышлению, необходимо сделать следующее для успешного написания оператора присванивания:
- Вспомнить синтаксис оператора присваивания
- Удалить fFoo1 и fFoo2
- Вызвать родительский оператор присваивания
- Сделать копии fFoo1 и fFoo2 у правой части оператора
- Вернуть ссылку на себя
В коде это будет выглядеть следующим образом:
Boo& operator=(const Boo& other)
{
delete this->fFoo1;
this->fFoo1 = nullptr;
delete this->fFoo2;
this->fFoo2 = nullptr;
SuperBoo::operator=(other);
if(other.fFoo1)
this->fFoo1 = new Foo(*other.fFoo1);
if(other.fFoo2)
this->fFoo2 = new Foo(*other.fFoo2);
return *this;
}
Это я и выслал в ответ на «тестовое задание», на что мне было сказано, что с заданием я не справился.
До сих пор гадаю, где же ошибка? На ум, конечно, приходит консистентность данных, защита от сбоев при выделении памяти и прочие кошерные вещи, но тут уже мой разум пасует — не настолько хорошо я знаю С++.
Deflated Soul
Случайно от подруги узнал, что наша музыка ныне доступна для покупки в iTunes. Видимо, барабанщик барыжит. В общем, все как у взрослых — с обложкой и возможностью предварительного прослушивания. Кому понравится — налетай, торопись, покупай живопись.
-
Categories
-
Archives
- May 2017
- April 2017
- March 2017
- January 2017
- September 2016
- July 2016
- May 2016
- March 2016
- December 2015
- November 2015
- September 2015
- May 2015
- March 2015
- December 2014
- November 2014
- October 2014
- September 2014
- August 2014
- July 2014
- June 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- September 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- March 2013
- February 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
-
Meta