Re[30]: Они сделали дерьмо опять
От: chaotic-kotik  
Дата: 21.05.20 20:07
Оценка:
Здравствуйте, lpd, Вы писали:


lpd>Самое простое это неудобные случаи когда время жизни объекта не совпадает со временем жизни переменной.


это точно также работает и с умными указателями

shared_ptr<Foo> x = ...;
...
x.reset(new Foo());
...
x = y;
...



lpd>И например может быть два объекта со счетчиками ссылок, которые нужно удалять вместе, или с более сложной логикой. Или нужно выделить ресурс в середине одной функции, а освободить в середине совсем другой, не связаной напрямую с первой. Я понимаю, что можно исхитриться, но это же неудобно.


два объекта со счетчиками ссылок которые нужно удалять вместе, ты и на чистом Си не удалишь вместе не нарушив инвариант счетчика ссылок

std::unique_ptr<Foo> bar() {
  ...
  return std::make_unique<Foo>();
}

void buzz(std::unique_ptr<Foo>&& foo) {
  ...
  foo.reset();
  ...
}

buzz(foo());


lpd>Вообще идея связывать время жизни переменной и какие-то операции по освобождению ресурсов довольно сомнительная. Время жизни переменной — это исключительно синтаксическая вещь, а освобождение ресурсов — императивная операция. И писать обертки над функциями только чтобы создать временную переменную, рассчитывая что где-то компилятор ее удалит, это удалять зубы через нос.


как раз наоборот, компилятор не забудет удалить, а вот кое кто предпочитает писать код с утечками, потому что так "проще"


lpd>Циклические ссылки могут понадобиться, и не всегда это плохая архитектура. С++ получается ограничивает программиста, или заставляет его думать об освобождении памяти.


я не говорил что их невозможно реализовать, но как правило это плохая архитектура

lpd>Я предпочту сборку мусора явному delete/free. Однако городить unique_ptr<>/shared_ptr<> в простых случаях, где не нужен подсчет ссылок, значит делать освобождение памяти неявным без причины, да еще с неудобным синтаксисом. И вот это уже является слепым следованием за фанатиками вроде Майерса.


ну вот чуть выше я предложил пример:

auto x = new X();
auto y = new Y(); // new throws exception here


vs

auto x = std::make_unique<X>();
auto y = std::make_unique<Y>();


в первом случае у тебя утечка памяти, потому что если второй new кинет bad_alloc или конструктор Y кинет исключение, объект на который указывает x не будет удален (предпологается что чуть ниже у тебя есть delete x; delete y;, который не выполнится, если будет выброшено исключение). Если ты попробуешь переписать код так, чтобы этого избежать, то получится жуткая каша, с unique_ptr такой проблемы нет

lpd>Тормозят объекты, выделяемые в большом количестве в цикле или массово. Их и можно удалять вручную, для ускорения сборки мусора. Где-то сборка мусора не подойдет, в таких проектах можно использовать free/delete + умные указатели.


— создание объектов в GC языках — очень быстрая операция, удаление тоже (так как у большинства объектов финализаторы пустые), тормозит stop the world фаза сборки мусора, когда GC останавливает все потоки и помечает все достижимые объекты

— free/delete в современных плюсах, как я уже писал, это code smell, попробуй найди хоть одну причину для их использования, кроме личных предпочтений — ничего не получится, т.к. для любого кейса найдется более подходящий и безопасный вариант нежели new/delete или же malloc/free
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.