Задачка по программированию

Dec 17, 2013 22:44


Давным-давно, когда я искал работу, мне прислали одну интересную задачку, которую я до сих пор гуглю на просторах интернета. Причем гуглю безответно - народ ломает голову, но ничего толкового придумать не может.

Я не самый большой специалист по С++, поэтому тешу себя мыслью, что если я ошибаюсь - меня поправят, а если нет - пусть статья выходит в топы гугла и висит там, дабы ее прекратили давать на собеседованиях. Потому что задача идиотская.

Звучит она так:

Перегрузка оператора присваивания

Пусть есть класс

class Boo : public SuperBoo

{

Foo* fFoo1;

Foo* fFoo2;

}

Где Foo - мономорфный класс, а класс Boo владеет указателями fFoo1, fFoo2.

Задача: перегрузить оператор присваивания для класса Boo.

Начнем с первого - с мономорфного класса. Все знают, что ООП состоит из полиморфизма, инкапсуляции и наследования. Определение полиморфизма можно прочитать в википедии, а пользуясь нехитрой логикой можно понять, что мономорфный - антоним понятия «полиморфный». Таким образом, в нашем случае, мономорфный класс - это класс, указатель на который всегда представляет его самого, а не его наследника.

То есть мы можем гарантировать то, что за Foo* скрывается класс Foo, а не какой-нибудь class MegaFoo : public Foo.

Второй вывод, который мы можем сделать из текста задачи - что класс Boo владеет указателями, а значит удаляет их в деструкторе. Таким образом, нам необходимо помнить о политике владения при написании оператора присваивания и четко удалять и создавать новые объекты.

Третий вывод позволяет нам сделать наличие суперкласса у Foo. Вполне возможно, что у SuperFoo есть оператор присвания, а значит нам необходимо его вызвать. Если же его нет - не беда, всегда есть оператор присваивания по умолчанию, просто копирующий блок памяти.

Таким образом, по нашему трезвому измышлению, необходимо сделать следующее для успешного написания оператора присванивания:
  1. Вспомнить синтаксис оператора присваивания
  2. Удалить fFoo1 и fFoo2
  3. Вызвать родительский оператор присваивания
  4. Сделать копии fFoo1 и fFoo2 у правой части оператора
  5. Вернуть ссылку на себя

В коде это будет выглядеть следующим образом:

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;

}

Это я и выслал в ответ на «тестовое задание», на что мне было сказано, что с заданием я не справился.

До сих пор гадаю, где же ошибка? На ум, конечно, приходит консистентность данных, защита от сбоев при выделении памяти и прочие кошерные вещи, но тут уже мой разум пасует - не настолько хорошо я знаю С++.

Комментировать запись на virtualmind.ru

программирование, странности, с++

Previous post Next post
Up