Занимательная задачка: понимание deep copy

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Господа, большие свои силы никто не хочет попробовать?
У меня другое направление. С++ - это язык, делающий упор на синтаксис. Лет 15 назад может и начал бы С++ изучать, но уже поздновато. До сих пор не понимаю, как живет язык в котором так велика вероятность совершить синтаксическую ошибку, о которой тебе никто ничего не скажет, потому что так тоже можно писать и приведет это к непредсказуемым последствиям.
Человек может волноваться на собеседовании или наоборот с лёгкостью решить задачку как ты этого хочешь
Меня однажды на собеседовании спросили, как, говорят, одной командой (операцией) узнать количество бит в байте. Я, блин, все инструкции x86 на тот момент, включая SSE перебрал - ну никак одной операцией не выходит.
Наконец ответили за меня: нужно просто взять это значение из массива [0..255]. Долго я им доказывал, что массив этот из воздуха тоже не возьмется, но тщетно.
Я, конечно, применял этот метод оптимизации и ранее, только видать задача была поставлена некорректно. Стоит ли ради одного байта массив городить? Так что собеседования, зачастую, не раскрывают потенциала человека. То, что человек не осилил задание говорит об одном из двух: либо человек не способен, либо у него просто не хватило времени.
И, кстати, в случае с числом бит в байте предложенные мною варианты работали не медленнее, а просто предлагали другой подход. И даже экономили целых 272 байта памяти, но даже тогда их уже никто не считал))
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Duncon, эта задачка на имплементацию самого обычного deep copy. Видимо ты даже по верхам не прочёл задание, если в штыки принял его, сразу повесив бирку "очень сложное задание на западный манер". Задача об основах основ. И очень грустно, что никто её не может решить нормально.

somewhere, а мне вот табличное решение пришло в голову в первую очередь, хотя я тоже застал ассемблер и баловался им в молодые годы :) Просто раньше сталкивался с табличной оптимизацией синусов и косинусов для ускорения расчётов координатных преобразований. А гугл, кстати, говорит, что в SSE4 появилась команда POPCNT.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

Romeo, я не писал что сложная, я писал что все эти задачки частные случаи и не могут раскрыть потенциал испытуемого.. И у меня таких проблем не возникает, кожу медленно много обдумываю узкие места, возможные сценарии, выхлоп обычно без ошибок (по мелочи недочёты/недосмотры только случаются).. Если бы рассматривал подобный вопрос - бурил бы весь проект и по факту скорее всего бы сделал /dev/null и переписал бы так, чтоб никогда в жизни к этому больше не возвращаться..(время ценный ресурс)
С++ для меня закончился примерно нацать++ лет назад, примерно по тем же причинам что и у somewhere.. Ушёл в паскальные языки и с тех пор очень доволен.. Ну а потом в вебку свалил, оказалось денег там больше и проще, ну а сегодня в ту сторону весь рынок сместился..
[syntax=Delphi] [/syntax]
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Duncon писал(а):ну а сегодня в ту сторону весь рынок сместился..
А вот это прямо в точку...
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Лет 15 назад может и начал бы С++ изучать, но уже поздновато. До сих пор не понимаю, как живет язык в котором так велика вероятность совершить синтаксическую ошибку, о которой тебе никто ничего не скажет, потому что так тоже можно писать и приведет это к непредсказуемым последствиям.
С точки зрения бизнеса у С++ есть очень слабое место в долгой компиляции. Вот в гугле пара человек внесли небольшое изменение в код и пересобирали его два часа на небольшом вычислительном кластере собранном из Xeon-ов. Потом в тот же вечер из комитета по стандартизации С++ пришли новости о том что о введении каких-то модулей на замену .h файлов они даже и не думают. Ну и что - собралось четверо человек и решили что С++-ом они сыты по горло. Решили взять Си и добавить в него динамические коллекции типа стрингов, массивов и хешей. Пригласили ветеранов - Кена Томпсона с Робом Пайком и сделали язык который их устраивает. Вот на этом С++ может серьезно погореть. Презрение к практическим проблемам бизнеса это серьезная ошибка.
2B OR NOT(2B) = FF
Аватара пользователя
Din666
Сообщения: 52
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

void Process() {
if ( ! m_pHuge ) { m_pHuge.reset(new CHuge); }
m_pHhuge->DoAction();
}
private: std::shared_ptr<CHuge> m_pHuge; наверно ))))

кстати void main() когда-то давно действительно собиралось на старом gcc. а вот корректно будет int main().....
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Неа. Тогда экземпляр CHuge будет у всех общий. Задача добиться такого же поведения, которое было у CWorker до правок.

А замечание по поводу main оставим на совести разработчиков компиляторов. На половине компиляторов сейчас это работает, на половине нет. Так или иначе, это не самое главное в задаче.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Din666
Сообщения: 52
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

да, Ты прав, тогда:

Код: Выделить всё

class CWorker {
    public:

        CWorker() = default;
        CWorker(const CWorker & rhs) { copy(rhs); }
        CWorker & operator=(const CWorker & rhs) { copy(rhs); return *this; }

        void Process() {
            if (! m_pHuge ) { m_pHuge.reset(new CHuge); }
            m_pHuge->DoAction();
        }

    private:
        std::shared_ptr<CHuge> m_pHuge;

        void copy(const CWorker & rhs) {
            if (this == &rhs) return;
            if ( rhs.m_pHuge ) { m_pHuge.reset(new CHuge(*rhs.m_pHuge)); }
        }
};
надеюсь теперь ничего не забыл (проверка selfcopy и инициализированности копируемого экземпляра )))))
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Din666 писал(а):да, Ты прав, тогда:

Код: Выделить всё

std::shared_ptr<CHuge> m_pHuge;
надеюсь теперь ничего не забыл (проверка selfcopy и инициализированности копируемого экземпляра )))))

По моему std::shared_ptr тут излишен. Они используется когда владелец инстанса не ясен. Тут же владелец инстанса вполне ясен, это CWorker, 1-to-1. Так что std::unique_ptr.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Абсолютно верное замечания от Absurd'а: shared_ptr тут излишен, так как owner очевиден. Если честно, то и unique_ptr тоже не особо нужен, так как у нас есть полный контроль за конструктором и деструктором CWorker. Можно обойтись и "сырым" указателем, не забыв в деструкторе сделать delete.

Ну и ещё один пунктик есть... как будет работать конструктор копирования и оператор присваивания, если в rhs внутренний указатель нулевой? Мне кажется, попахивает неинициализированными данными. А в случае оператора присваивания ещё и рассогласованностью состояний (если у нас указатель уже ненулевой, а у rhs - нулевой).

Вроде простая задачка на deep copy, а сколько каверзных мест :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить