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

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

Страницы: 1 2 3 4 5 6 Следующая »
KartonagnickЗабаненwww8 июля 20181:51#60
grishman
> ты уже разобрался почему виртуальное наследование не работает в конструкторах?
не тупи. все там работает.
у тебя проблемы с причиной и следствием.
DelfigamerПостоялецwww8 июля 20182:39#61
Wraith
Итак, утверждение:
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
А! ОП хотел сказать, что от созданных на стеке потомков std::enable_shared_from_this нельзя брать shared_from_this().
Но, вообще-то, дело тут вовсе не в std::enable_shared_from_this, о чём я и ответил:
Delfigamer
> Это не является особенностью enable_shared_from_this; это свойство присуще всем
> умным указателям - нельзя вызывать delete на указателе, полученном от стековой
> переменной.
Обрати внимание на конструкцию предложения - после слов «это свойство» я уточняю, из-за какого свойства на самом деле исходит запрет на вызов shared_from_this у автоматических объектов - «нельзя вызывать delete на указателе, полученном от стековой переменной».
А пример Картонажника - это банка с надписью "соль", в которой лежит гидроксид натрия. За такой код надо бить ремнём и лишать лицензии на кресты.

Ну и раз уж сказал, что тыкну:

[new.delete.single]
void operator delete(void* ptr) noexcept;
12 Requires: ptr shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced) operator new(std::size_t) or operator new(std::size_t,const std::nothrow_t&) which has not been invalidated by an intervening call to operator delete(void*).

Правка: 8 июля 2018 2:40

WraithПостоялецwww8 июля 20184:05#62
Delfigamer
Все остальные поинтеры (unique_ptr, бустовские scoped_ptr и intrusive_ptr) можно создавать для стековых объектов. И они будут работать корректно, хотя и бестолку, конечно.

shared_ptr - нельзя, но не потому что объект на стеке, и будут "проблемы с delete", а потому что shared_ptr буствоской реализации (теперь везде) требует наличия shared_section. С shared_ptr программа упадет еще до того как дело дойдет до delete.

DelfigamerПостоялецwww8 июля 20184:30#63
Wraith
> shared_ptr - нельзя, но не потому что объект на стеке, и будут "проблемы с
> delete", а потому что shared_ptr буствоской реализации (теперь везде) требует
> наличия shared_section. С shared_ptr программа упадет еще до того как дело
> дойдет до delete.
Смотри пример Картонажника. Если кастрировать шаред - то и его можно указать на стек, вот только без удалителя это уже будет не шаред, а нечто печальное и уродливое.
_

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

Правка: 8 июля 2018 4:56

KartonagnickЗабаненwww8 июля 201816:50#64
Delfigamer
> А пример Картонажника - это банка с надписью "соль", в которой лежит гидроксид
> натрия. За такой код надо бить ремнём и лишать лицензии на кресты.


это банка с надписью "Виджет".
что там под капотом - не твоё собачье дело.

сегодня - шаред, завтра выйдет новая версия. и может быть что-то другое.

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

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

DelfigamerПостоялецwww8 июля 201818:20#65
Kartonagnick
Даже если ты спрячешь все свои проблемы внутри большой банки "виджет", это не нисколько не отменяет их проблемности.
Банку "виджет" можно запереть наглухо только в двух случаях:
1) когда твой код расходует ноль тактов процессора и ноль байт памяти, причём как в рантайме, так и в компиляции, содержит весь возможный функционал о котором только можно подумать и при этом не содержит ни одной ошибки и не ломается ни при каких обстоятельствах;
2) весь код на следующий же день отправится на помойку и о нём больше никто и никогда не вспомнит.
Во всех остальных случаях, рано или поздно обязательно появятся причины доработать внутренности твоего "виджета". В этот момент весь гной и зловоние тут же полезут наружу.

Правка: 8 июля 2018 18:22

KartonagnickЗабаненwww10 июля 201813:56#66
Delfigamer
> Даже если ты спрячешь все свои проблемы внутри большой банки "виджет", это не
> нисколько не отменяет их проблемности.
> Банку "виджет" можно запереть наглухо только в двух случаях:

пьяный шталь?

innuendoПостоялецwww11 июля 201810:59#67
grishman
> В C# скорость выделения памяти в ~2.7 раза выше чем в C++.

ой, как нехорошо получилось

DelfigamerПостоялецwww11 июля 201818:35#68
grishman
> В C# скорость выделения памяти в ~2.7 раза выше чем в C++.
А освобождать память кто будет? Пушкин?
DinosaurПостоялецwww12 июля 20189:38#69
grishman
> В C# скорость выделения памяти в ~2.7 раза выше чем в C++.
> В С++ скорость заполнения массива в ~1.95 раза выше чем в C#.
C++ Debug
Init time:94.014230
Fill time:84.012347

C++ Release (-O2 -Ot)
Init time:11.094430
Fill time:84.029983

C# Debug
init time:115,437
fill time:82,4084

C# Release
init time:109,3725
fill time:31,2421

C++ — MSVC 15.7.5
C# — .NET Framework 4.7.2

Мне лень возиться с дизассемблированием результатов работы JIT-компилятора для определения причин разницы в скорости заполнения, но C++ с выключенными оптимизациями аллоцирует на 14% быстрее оптимизированного C#.
"ой, как нехорошо получилось" © innuendo

DelfigamerПостоялецwww12 июля 20189:43#70
grishman
Dinosaur
Вы не на синтетической фиговине замеряйте, а на реальной задаче, причём с большим объёмом и длинными вычислениями - чтобы в процессе работы память хотя бы по десятку раз целиком занималась и освобождалась.
Стоимость отдельных операций ничего не значит, потому что это вообще ни разу не равнозначные операции, аллокация в плюсах и аллокация в решётке.
grishmanПользовательwww13 июля 201815:11#71
Delfigamer
> grishman
> > В C# скорость выделения памяти в ~2.7 раза выше чем в C++.
> А освобождать память кто будет? Пушкин?
тоже самое хочу спросить у разработчиков shared_ptr:
If any std::weak_ptr references the control block created by std::make_shared after the lifetime of all shared owners ended, the memory occupied by T persists until all weak owners get destroyed as well, which may be undesirable if sizeof(T) is large.

зачем нужны умные указатели, которые даже память освободить не могу. В C# я хотя бы могу рассчитывать на сборщика мусора - он освободит память если все ссылки на объект будут потеряны
Dinosaur
> Мне лень возиться с дизассемблированием результатов работы JIT-компилятора для
> определения причин разницы в скорости заполнения, но C++ с выключенными
> оптимизациями аллоцирует на 14% быстрее оптимизированного C#.
Я уже писал почему в С# быстрее аллокация, но видимо и это поленились прочитать. С++ может быть быстрее только в одном случае - если использовать кастомные аллокаторы.
EugeneУчастникwww13 июля 201815:22#72
grishman
> Я уже писал почему в С# быстрее аллокация, но видимо и это поленились
> прочитать. С++ может быть быстрее только в одном случае - если использовать
> кастомные аллокаторы.
Я, кстати, не понял, хоть и прочитал.
мб есть годный материал на тему?
*Lain*Пользовательwww13 июля 201818:39#73
Eugene
Там просто аллокации малых объектов (несколько килобайт) за О(1) и практически без затрат памяти на фрагментацию кучи

Правка: 13 июля 2018 18:40

DinosaurПостоялецwww14 июля 20180:26#74
grishman
> зачем нужны умные указатели, которые даже память освободить не могу.
std::make_shared выделяет память одним куском под "control block" и объект. Возможность вернуть системе часть ранее аллоцированного блока, оставив валидным указатель на его начало — слишком специфическая вещь, чтобы закладываться на неё в стандарте языка. Шарпу на это пофиг, т.к. у него есть нянька-надзиратель в виде виртуальной машины, имеющей полный контроль над выполняемым в ней кодом и потому способной проделывать любые фокусы незаметно для этого самого кода. У C++ такого контроллёра нет, как нет и рантаймовой информации, с помощью которой гипотетический гипервизор/виртуальная-машина-наподобие-VirtualBox мог бы обновить все указатели на переместившийся "control block" после уничтожения объекта.

> Я уже писал почему в С# быстрее аллокация
> С++ может быть быстрее только в одном случае - если использовать кастомные аллокаторы.
Можно и без кастомных аллокаторов обойтись — в синтетике типа той, что в #51, когда [около]нулевая фрагментация кучи избавляет от необходимости искать свободный блок подходящего размера, сама по себе аллокация в C++ будет не особо отличаться от дотнетовской. Зато необходимость инициализации переменных дефолтными значениями означает, что в C# затраты на

arr[i] = new double[columns];
включают в себя, помимо самой аллокации, ещё и
for (int j = 0; j < columns; j++)
    arr[i][j] = 0.0;

Т.е. "init" в C# почти эквивалентен "init + fill" в C++, что вполне подтверждается результатами в #69.

Страницы: 1 2 3 4 5 6 Следующая »

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

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