Обновить
0
0

Пользователь

Отправить сообщение

привести искуственный пример самострела можно в любом языке. И точно так же невозможно вручную проконтроллировать отсутствие его в достаточно большой кодобазе. Ну и не просто так рекомендуется использовать make_unique.

я о том, что в силу особенностей языка использование unique_ptr на спасет ни от чего, выстрелить в ногу можно точно так же, как и 20 лет назад
просто тогда б-м прошаренный народ писал свои обертки и использовал всякие creator patterns
а вот наличие gc от такого вполне так себе гарантируeт

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

похоже, мы всю дорогу о разном говорили.
unique_ptr тут вообще сбоку, говорить надо было про auto_ptr

ну по сути накладные расходы на аллокацию заменены куда большими во время сборки мусора, которая еще и блочит все треды.

ну так в реалиях-то как раз эта сборка происходит редко, да и сбор в первой генерации быстрый. При этом не будет out of memory из-за дефрагментации памяти

какой блин "дьявол" то? У вас есть дополнительные расходы на механизм, который своим существованием не может сэкономить ресурсы даже теоретически.

теоретически - да
А на практике - очень даже. Потому что сбор мусора происходит редко

то, что язык сложнее, не значит, что писать на нём тоже сложнее.

именно это оно и значит:))

Взять например питон - на дистанции в 1-10 kloc писать на нём проще чем на чем угодно другом; писать на питоне проект на 100+ kloc - самоубийство

ну так давайте не питон возьмем, а сишарп, или там, свят-свят, жаву

вы посмотрите средние ЗП плюсовиков и джавистов, удивитесь

да зачем мне смотреть, мы весь прошлый год искали
сишарп/жава - без проблем, а сишников тока в экс-ссср и нашли, дядьку уже за 40

Нелогично было бы если бы приходилось для каждого объекта unique_ptr писать финализатор, который вызовет ~T(),

ну в с++ наверное
а в сишарпе это просто деструктор

а память освобождалась хитрым и тормозным неявным способом, останавливающим все потоки исполнения

финализация идет в отдельном потоке, о чем вы?

И еще раз замечу - вы чересчур переоцениваете необходимость своевременной чистки памяти. В частных случаях - да, в целом нет

У него просто нет копирующего конструктора

auto test = new int(10);
auto p = std::make_unique<int*>(test);
auto p1 = std::make_unique<int*>(test);

а так?

Прямым текстом сказано вообще-то:

дык а как это обеспечивается на уровне реализации этого UP? что мне мешает сделать указатель на обьект при помощи new и запихнуть его в 2 разных UP? Тока не говорите, что здравый смысл - это а) как повезет б) в сложных codebases вручную все проконтролировать невозможно

Объявили объект внутри блока {} - он удалится когда закончится этот блок

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

class AutoCheck
{
public:
	AutoCheck(int i)
	{
		inner = i;
	}
	
	~AutoCheck()
	{
		inner = 0;
	}

private:
	int inner;
};
int main()
{
    auto test = new AutoCheck(10);
	  {
    	auto p = std::make_unique<AutoCheck*>(test);
    	auto p1 = std::make_unique<AutoCheck*>(test);
    }
}

unique_ptr называется unique не просто так, два unique_ptr не могут ссылаться на один объект.

в документации ничего про это не сказано. Это отдано на откуп программисту, что ли? Ну так это и есть та самая веревка, которой можно выстрелить себе в ногу

Нет, обычно полагаются на вызов деструктора при выходе из скоупа

Понятно

Тогда мы снова возвращаемся к ситуации, когда мне (в случае необходимости немедленного освобождения памяти) нужно писать ручное удаление, которое еще и черти к чему приведет

О чем я и говорю, очень примитивная обертка, не гарантирующая, по сути, ни от чего

это в теории там просто непрерывный последовательно заполняющийся кусок памяти. На практике это конечно же не работает (фрагментация уводит потребление памяти в космос) и приходится реализовывать полноценные аллокаторы, распределяющие память внутри этой managed heap.

да какая теория? При каждом коллекте gc дефрагментирует managed heap. Это гарантированно всегда непрерывный кусок памяти
Вот чесслово, почитайте доку уже
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

а это не важно. Сколько ни оптимизируй/усложняй стратегию сборки мусора, отрицательной или даже нулевой её стоимость не станет.

не станет, но дьявол кроется в деталях

Во-первых, вы предполагаете что разработка на языках с GC быстрее чем на тех же плюсах. Начиная с с++11 это как минимум не очевидно и не безусловно

вполне очевидно; c++ заметно более сложный и дорогой в обслуживании язык. Начиная с разницы между обьектами, ссылками и указателями и заканчивая упоминавшимися вирт. деструкторами. Да и прочее, те же ексепшены взять

При сравнимой стоимости разработки ценник в $1m за облачную инфраструктуру покажется куда привлекательнее $5m.

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

ООП по версии Алана Кая конечно больше похож на то, что нынче называют "акторами", но инкапсуляция в его парадигме всё так же фундаментально необходима

да все равно unique_ptr под это дело не очень попадает
инкапсуляция - сокрытие данных, которые определяют состояние обьекта, а указатель внутри up него не определяет, это просто обертка

от программиста на C++ обычно ожидается хотя бы поверхностное знакомство с STL

по статье это не заметно:)

файловые дескрипторы, сокеты, мьютексы в конце концов. RAII дает куда больше чем простое освобождение памяти.

да обычный менеджмент ресурсов. Мы еще в 2000х писали auto critical sections, ничего тут особенного нет, раз открыл - закрой; а если еще и будешь делать это через спец-обьект на стеке, так и вообще молодец

вы сильно недооцениваете моё понимание плюсов и сильно переоцениваете моё понимание джавы/шарпа.

ну, вот у меня был такой опыт. Очень освежающий!! Когда через пару дней активной разработки мы вдруг сообразили - мама дорогая, это ж не дотнет, надо ж самим обьекты прибирать! И началось..

Единственный вариант когда managed heap теоретически может быть быстрее - если специфика нагрузки хорошо ложится на конкретный аллокатор.

? Managed heap - это непрерывный кусок памяти, уже заранее выделенный вирт. машиной, какие там спец аллокаторы. Для небольших обьектов никакой там магии нет

Подробнее можете ознакомиться в этом докладе

в докладе говорится, что гц добавляет оверхед - с этим-то я вообще не спорил; я говорил, что а) на современном железе на него чаще всего пофиг, б) помещение обьекта в управляемую память - быстрее

ну и докладчик не очень знает про современные стратегии сборки мусора:)

Парадигма ООП основана на инкапсуляции

нууууу... Об этом до сих пор спорят, на чем же она основана. А один из основателей так и вообще сказал, что он имел в виду скорее event driven, а не вот ЭТО

действительно, какие проблемы выжрать 300 гигов памяти на серваке, а потом потратить десяток секунд на её очистку, пока все остальные приложения ждут...

ну так если вы настроили вирт. машину так, что ей можно 300 гиг памяти, кто ж виноват

Кроме того, железо нынче дешевое, а программисты дорогие, так что, опять же, это не такая уж проблема.

Иными словами, пофиг, кто сколько сожрал памяти, если ее хватает

собственно в этом и проблема. Вы разве никогда не сталкивались с проблемами типа заканчивающихся файловых дескрипторов

нет, конечно, потому что я гарантированно закрываю открытые файлы

IDisposable - это просто интерфейс, позволяющий имплементировавшему его классу быть использованным в конструкции using. Как имплементацию напишете, так и будет - ровно как и в случае с деструктором вашего файлового обьекта

ну да, там поколения еще есть, если я правильно помню.

там много чего есть:)

Это я к тому, что в плюсах с этим проще, там RAII с умными указателями подходят и используются для обоих случаев - и для освобождения ресурсов, и для автоматического вызова закрывающей функции

а если мне закрыть надо, а ресурс освобождать нет?:) Они ж довольно примитивные, unique_ptr эти. Никто ж не строит графов обьектов и не проверяет ссылки на них; вызвал кто reset, и все. А если на указатель внутрях еще один unique ссылается?

Ну и вроде все равно надо явно вызывать что-то типа unique_ptr.reset(nullptr), нет?

Пора, пора!
Еще kotlin native есть, к слову
У меня был как-то проект, полуembedded (десктоп клиент и управляющая программа на железе), так там на железе натурально комп с winnt стоял, мы туда даже студию вкорячили, для отладки:)) Там с go наверное не было бы проблем, но его тогда и не было еще

Автору - welcome to the club!

ну если перекладывать jsonы из таблички в табличку(ц), то не нужно, конечно!

так статья, по сути, не об умении программировать, а о знании некоторых специфических (пусть и широко распространенных) особенностей фреймворка (std)

Мне такое странно, фреймворк и фреймворк, нормальный прогер основные положения выучит за пару месяцев, это не рокет саенс. А тут прям такое внимание

на первом месте - многословность и просто адское количество boilerplate code. У меня постоянно было ощущение, что я что-то обьясняю умственно отсталому человеку - очень подробно, со всеми мелкими деталями и т.п., каждый раз повторяя одно и то же. Сюда же отсутствие лямбд, linq и проч. Хотя в 11 жаве это уже все есть в полный рост, но оно все равно крайне многословное

Второе - женерики. После дотнета это был прям-таки удар!!!:) Они в жаве не более чем syntax sugar

третье - очень странная имплементация интефейсов (после сишарпа). Не могу сказать, что плохая, но странная

то Spring для меня просто тихий ужас

бог миловал:)

Я уже с десяток лет с подобным работаю. Именно на плюсах. И таких проектов все больше и больше.

а на Go или там Rust народ не хочет переходить? Не помню, какой там из них в нативный код компилится

А вот на C++ по ряду причин такое сделать получится легко, и как показывает практика, очень многие пытаются так делать. Об этом и статья.

это понятно, я все еще помню жаркие дискуссии с vs c++ в начале этак 2000х. "Веревка достаточной длины, чтоб выстрелить себе в ногу", а как же:)
Но это, имхо, не достоинство прикладного языка

У меня там не стрелка, а "меньше" было:) Я имел в виду, что вам C# нравится больше, чем Java, а Kotlin больше чем C#, верно?

да, именно так. Хотя сишарп не сказать чтоб не нравится, просто К. чуть удобнее, да и привык

В том же Шарпе это будет не "когда они не нужны", а "когда они не нужны и до них наконец-то доберется сборщик мусора". Поэтому в языке пришлось изобретать костыли с using.

ну что вы, давным давно уже не так

запустится он, когда у него перестанет хватать памяти под новые обьекты, при этом, все обьекты он проверять на удаление не будет. А пока ее хватает, какие проблемы
Была тут вроде переводная статья про gc как эмулятор бесконечной памяти

что до using - это не про чистку памяти, это про гарантированный вызов некоей закрывающей функции, например, чтоб файл закрыть, или там курсор по базе
IDisposable никоим образом не гарантирует освобождение ресурсов, это просто интерфейс
такой аналог try/finally

Информация

В рейтинге
Не участвует
Откуда
Laval, Quebec, Канада
Зарегистрирован
Активность