Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / С++ где взять shared_ptr когда он так нужен? [РЕШЕНО] (2 стр)

С++ где взять shared_ptr когда он так нужен? [РЕШЕНО] (2 стр)

Страницы: 1 2 3 4 5 6 Следующая »
*Lain*Постоялецwww6 июля 20188:51#15
=A=L=X=
многопоточненько
и вик_птр.лоск поддерживает)
=A=L=X=Постоялецwww6 июля 20188:56#16
*Lain*
> многопоточненько
Если нужна многопоточность или конст-корректнес, как я писал - все карты в руки. Если многопоточность не нужна, то не надо за неё платить.
> вик_птр.лоск поддерживает)
Интрузивам не нужен слабый указатель, т.к. у них нет проблем с сырыми указателями, слабый=сырой. Никакой проблем сослаться на родителя указателем и не залочить его нет.
EugeneУчастникwww6 июля 201811:07#17
=A=L=X=
Сырые указатели экспайриться не умеют. Нихрена не замена.
=A=L=X=Постоялецwww6 июля 201812:23#18
Eugene
> Сырые указатели экспайриться не умеют. Нихрена не замена.
Единственная реальная польза от этого - отладку облегчает когда надо найти где программа пытается работать с убитым объектом.
Сценарий использования когда "на всякий" случай держится вик_птр, чтобы мало ли вдруг может использовать если ну вдруг - это чаще или не нужно или переголова. Я в практике вообще не встречал такой необходимости.
Поэтому основное назначение weak_ptr в std:: - это именно как сослаться на родителя не залочив его и не отстрелив себе ногу сырым указателем.
EugeneУчастникwww6 июля 201813:08#19
=A=L=X=
> Я в практике вообще не встречал такой необходимости.
Да откуда же вы такие повылазили. Пару дней назад в соседнем треде я очень похожее слышал.
Есть целая пачка задач, для которых weakptr - естественное и единственное аккуратное решение.
Не-удерживающие кеши, асинхронные арбайтеры, слабосвязные динамические системы типа ecs
=A=L=X=Постоялецwww6 июля 201813:13#20
Eugene
Есть целые языки где никогда не было слабых ссылок, но они прекрасно без них жили.
Связано это с тем, что любой не удерживающий кеш можно реализовать прямыми руками и как правило он и не нужен иного дизайна, нежели пряморукого с нормальным контролем что и зачем  кешируется, а не когда объект инвалидируется просто потому что на него перестали ссылаться. Кеш на то и кеш чтобы умно разруливать, учитывать историю. И т.п. и т.д. Все примеры использования слабых ссылок на подобную тему что я видел были высосаны из пальца.
А вот у shared_ptr слабые ссылки нужны просто чтобы не отстрелить себе ногу.

Правка: 6 июля 2018 13:15

EugeneУчастникwww6 июля 201813:40#21
=A=L=X=
Я в соседнем треде так и не выжал из чувака хорошего, годного примера кеша без слабых ссылок.
И нет, я не хочу вместо слабых ссылок делать ручное удаление бесхозных объектов по таймеру.
Умные кеши это круто, но не всегда нужно.
=A=L=X=Постоялецwww6 июля 201814:22#22
Eugene
> годного примера кеша без слабых ссылок.

Я не знаю где сам такой кеш может быть годным.
Мы вот на сайте игродельства - допустим кеширование текстур - оно резко противоречит тому что ты пытаешься рассказывать, мало того что надо удерживать, еще и предсказывать заранее попытки обращения и т.п.

ardruПостоялецwww6 июля 201814:23#23
Евгений, в Си++ почти всё делается через библиотеки. Есть множество библиотек для всевозможных сценариев выделения и освобождения памяти. Попытки писать низкоуровневый код, не зная всех тонкостей языка, неизбежно приводят к нервным расстройствам, (когда сегфолты начинают срабатывать только на некоторых платформах или при сложных комбинациях факторов).

Правка: 6 июля 2018 14:30

=A=L=X=Постоялецwww6 июля 201814:25#24
Eugene
> И нет, я не хочу вместо слабых ссылок делать ручное удаление бесхозных объектов
> по таймеру.
Неважно что ты хочешь, протухшие ссылки всё равно надо чистить. По таймеру, да.
grishmanПользовательwww6 июля 201814:52#25
Delfigamer
> grishman
> > А с этим механизмом shared_from_this объекты класса нельзя создавать на
> > стеке,
> > как минимум.
> Разве? Почему?
It is permitted to call shared_from_this only on a previously shared object, i.e. on an object managed by std::shared_ptr<T>. Otherwise the behavior is undefined

Delfigamer
> grishman
> > не понимаю зачем вообще нужен этот несчастный С++, когда уже есть C# с
> > автоматической сборкой мусора
> tl;dr C++ нужен тогда, когда есть жёсткие ограничения на память, на время
> выполнения или нужно работать напрямую с оборудованием компьютера. Например - в
> ядре игрового движка, где нужно отрендерить сцену, посчитать физику, собрать
> ввод с контроллеров и связаться с сервером и при этом всё успеть за 16мс и
> уложиться в несколько мегабайт.
Оборудование и С++ никак не связаны, это заблуждение. Объекты рендерятся видеокартой; физика тоже может считаться в шейдере, ну или софтварно - однако я не вижу смысла использовать арифметические операции С++ - они ничем не лучше аналогичных в C#; ввод с контроллеров осуществляется через API операционной системы - ты его быстрее не сделаешь, тоже самое с сокетами для работы с сетью. Но ты таки озвучил применение С++ - оптимизация работы с памятью. Хотя даже это потенциальное преимущество - довольно спорное, потому что аллокация памяти в C# работает быстрее, и такой эффективный сборщик мусора на С++ всё равно технически не навелосипедить.

Delfigamer
> Главный пример автоматизации в плюсах - это RAII. Объекты в плюсах можно
> настроить так, чтобы при их создании и уничтожении автоматически производились
> какие-то дополнительные действия.
Вообще-то смысл RAII в другом:

получение некоторого ресурса неразрывно совмещается с инициализацией, а освобождение — с уничтожением объекта.

Надо отметить что С++ с этой задачей справляется хреново, по следующим причинам:
1) Отсутствие поддержки виртуальных функций внутри конструкторов. Это ограничение следует учитывать при дизайне архитектуры: или отказаться
    от виртуальных функций, или же повесить стикер на монитор что в конструкторах их использовать нельзя, или же просто отказаться от
    инициализирующих конструкторов
2) Сложности при виртуальном наследовании. При использвании виртуального наследования, в инициализирующих конструкторах производного
    класса следует явно вызывать инициализирующие конструкторы базовых классов, на всех уровнях иерархии. Без явного вызова базового
    конструктора С(1), будет вызван конструктор по умолчанию (без параметров).
В целом RAII, даже если предположить что эти проблемы можно решить, не позволяет инициализировать и деинициализировать объект несколько раз в ходе его жизненного цикла. Ведь если вы борец за бережное использование памяти, то это проблема. В любом случае из-за предыдущих двух пунктов следует, что лучше для инициализации объектов использовать метод Class::Init.

Delfigamer
> В целом - при правильном применении C++ предоставляет возможность
> оптимизировать программу до такого же уровня, какой доступен в Си, при этом не
> жертвуя безопасностью и выразительностью исходного текста программы.
Нет ни выразительности, ни безопасности. В любой момент можно сломать конструкцию на любом уровне абстракции, и компилятор даже слова не скажет. Ты лишь сегодня узнал как в действительности работает механизм shared_from_this, и за это время мог в любой момент прострелить себе ногу.
Какая выразительность, если мне нужно наследоваться вот от этого std::enable_shared_from_this<T>, и при этом помнить что объект нужно создать в куче и обернуть в shared_ptr чтобы всё это работало? На каждую функцию в STL по целому абзацу противопоказаний "что с ней нельзя делать чтобы не убиться". STL - просто стандартизированный набор велосипедов не с самым лучшим API, к которому вынужденно пришли чтобы хоть как-то договориться между собой, и начать работать над общим кодом.


Delfigamer
> кресты очень легко применить неправильно
Вот с этого тезиса и следовало начинать свой доклад.

Поэтому, входить в кресты
> рекомендуется, только уже имея хороший опыт использования нескольких других
> языков, например - набор из того же C#, Python, Scheme и PHP.
С++ появился в 1983, C# - в 2001. Выходит чтобы следовать твоим рекомендациям, программистам С++ следовало повременить с программированием и подождать лет так 18. На самом деле всё проще, С++ - это Си-подобный язык, который придуман Си-программистами.

ardruПостоялецwww6 июля 201815:53#26
grishman

> С++ появился в 1983, C# - в 2001. Выходит чтобы следовать твоим рекомендациям,
> программистам С++ следовало повременить с программированием и подождать лет так
> 18. На самом деле всё проще, С++ - это Си-подобный язык, который придуман
> Си-программистами.

Не всё так просто. Так было в начале, но потом появился "комитет" https://isocpp.org/std/the-committee , в который входит Майкрософ (которым нафиг не нужен конкурент С#), Qt (которые настолько любят смарт-поинтеры что наплодили их немеряно http://blog.qt.io/blog/2009/08/25/count-with-me-how-many-smart-po… does-qt-have/ ), Google - которым нафиг не нужен конкурент ихнему Go и много других компаний со своими хотелками.

Си разрабатывался исходя из того, что на компьютер с 64 килобайтами памяти захотели уместить препроцессор, компилятор, исходник программы и заголовки библиотек, которые она использует. Си++ раздули до такого монстра, что скоро не будет уже возможности делать компиляторы, поддерживающие все фичи языка, как это случилось в своё время с PL/1 от IBM... В некоторых случаях, программисты умышленно отказываются от тех или иных фич (например, исключений), или от растолстевших библиотек типа Boost, Qt, Juce и прочих неудобных зависимостей, навязывающих каждый свои типы (строк, массивов и т.д), вместо стандартных. Juce - вообще, попытка сделать Си++ похожим на Джаву...

Современный Си++ можно сравнить с большим рестораном, где меню состоит из 25 увесистых томов на китайском, причём многие блюда, в сочетании с многими другими ядовиты, при этом яд может начать действовать через несколько лет, а посетители постоянно требуют добавить в меню "ну вот точно такие же гамбургеры как в МакДональдсе"... В таких случаях друзья обычно рекомендуют заказать какой-нибудь неострый суп, и надеяться что в крайнем случае вовремя успеешь добежать до ближайшего туалета.

Правка: 6 июля 2018 16:19

=A=L=X=Постоялецwww6 июля 201816:41#27
grishman
> It is permitted to call shared_from_this only on a previously shared object
Передавать объект на стеке в функцию через умный указатель - хреновая идея сама по себе. Так делать не надо.
Или не создавать их на стеке или переделать под интрузивный смарт, а в функции передавать ссылки/указатели. Ну и разумеется никогда не передавать объект на стеке в место где на него будет делаться смарт - это ошибка.

Правка: 6 июля 2018 16:43

EugeneУчастникwww6 июля 201817:06#28
=A=L=X=
> Я не знаю где сам такой кеш может быть годным.
Ну, я тоже не могу сходу найти реальную задачу, где я такой кеш использовал.
Но допускаю существование таких задач.
Там, если ты помнишь, были и другие примеры пользования weakptr, не только слабый кеш.

ardru
> (когда сегфолты начинают срабатывать только на некоторых платформах или при
> сложных комбинациях факторов).
Я заметил любопытную корелляцию.
Чем меньше разработчик пишет код жопой, тем меньше у него сегфолтов.
Я точно помню, как в 18 лет мог ковыряться целую неделю с сегфолтом.
Сейчас же я не могу вспомнить, когда последний раз у меня было что-то подобное.

Теперь я просто пишу код так, чтобы в нем не могло быть сегфолтов.
Контейнеры и умные указатели — хороший инструмент для такой задачи.

Правка: 6 июля 2018 17:07

ardruПостоялецwww6 июля 201817:59#29
Eugene
Хорошо. Как вам поможет умный указатель, когда, например, std::vector переполнился и переехал на новое место?
Страницы: 1 2 3 4 5 6 Следующая »

/ Форум / Программирование игр / Общее

2001—2018 © GameDev.ru — Разработка игр