Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Допустим, есть некий класс и в зависимости от того, является ли экземпляр const или non-const у этого экземпляра либо нет реализации деструктора, либо она есть. Кто как решает подобную задачу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 15:39 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devКто как решает подобную задачу?это какая то странная задача)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 15:48 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
egorych, есть необходимость изменить поведение экземпляра класса, когда он const, но если обычные методы можно сделать const и они будут вызываться только для const указателя/ссылки на объект, то конструкторы и деструкторы сделать const, разделив таким образом поведение при создании/разрушении, нельзя. Вот я и спрашиваю - кто и как решал подобную задачу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 16:19 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devegorych, есть необходимость изменить поведение экземпляра класса, когда он const, но если обычные методы можно сделать const и они будут вызываться только для const указателя/ссылки на объект, то конструкторы и деструкторы сделать const, разделив таким образом поведение при создании/разрушении, нельзя. Вот я и спрашиваю - кто и как решал подобную задачу? Это где такому учат? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 17:09 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devДопустим, есть некий класс и в зависимости от того, является ли экземпляр const или non-const у этого экземпляра либо нет реализации деструктора, либо она есть. Кто как решает подобную задачу? Вернись в постановке реальной задачи, а не к черезжопному представлению, как ее делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 17:47 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devegorych, есть необходимость изменить поведение экземпляра класса, когда он const, но если обычные методы можно сделать const и они будут вызываться только для const указателя/ссылки на объект, то конструкторы и деструкторы сделать const, разделив таким образом поведение при создании/разрушении, нельзя. Вот я и спрашиваю - кто и как решал подобную задачу? Ну как вариант, можно чекать внутри объекта если хотя бы раз у него вызывался неконстантный мембер, то он неконстантный и уже в деструкторе принимать решение на основе этого флага. Но это дурно пахнет, если честно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 17:57 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devконструкторы и деструкторы сделать const, разделив таким образом поведение при создании/разрушении, нельзяи это правильно, ибо класс с константным конструктором не получится создать, а с константным деструктором - разрушить ))) PS смотри в stl, там сделали отдельные классы для таких извращённых случаев, iterator и const_iterator как пример ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2018, 19:10 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Если я всё правильно понял, конструкторы вызываются для константных и не константных объектов. Разница только в точке вызова. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 05:12 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
egorychи это правильно, ибо класс с константным конструктором не получится создать, а с константным деструктором - разрушить ))) PS смотри в stl, там сделали отдельные классы для таких извращённых случаев, iterator и const_iterator как примерВ том-то и дело, что при инициализации константного объекта он может быть проинициализирован константными значениями без их копирования в кучу, т.е. ссылаться на них, а при разрушении, естественно, не должен пытаться очистить эти ресурсы. Совершенно не хочется проверять в деструкторе, где именно находится ресурс - в куче или в ресурсах бинарного модуля. По всей видимости, придётся как-то выкручиваться через спецификацию шаблона. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 09:31 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
CEMbЕсли я всё правильно понял, конструкторы вызываются для константных и не константных объектов. Разница только в точке вызова.И точка вызова у них может быть одна и та же. Разница лишь в том, что при вызове константного метода ему прилетает константный this со всеми вытекающими. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 09:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devИ точка вызова у них может быть одна и та же. Разница лишь в том, что при вызове константного метода ему прилетает константный this со всеми вытекающими. При вызове ему прилетает указатель и никто не знает какой он. https://msdn.microsoft.com/ru-ru/library/07x6b05d.aspx]Ключевое слово const указывает, что значение переменной является постоянным и сообщает компилятору , что программист не должен его изменять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 11:16 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduser, что мешает проверить? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Результат компиляции: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 11:47 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_dev, С функциями Set const не используется обычно. Но вы знаете толк в извращения! Это происходит только в момент компиляции. Мой вариант работает. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 12:02 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduserЭто происходит только в момент компиляции.Естественно! Где же еще? :) Скомпилированный бинарный модуль не хранит информацию о спецификаторах. Ты же понимаешь, что доступ к любому члену экземпляра класса осуществляется по неявному указателю this, который можно указывать, а можно и не указывать в реализации метода, а доступ по константному указателю, это доступ read-only. P.S. Кстати, попробуй в моём примере строку с ошибкой заменить на строку из комментария. ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 12:09 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_dev, Так ты что хочешь получить в результате? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 12:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduserrdb_dev, так ты что хочешь получить в результате?Об этом я уже всё написал выше, а сейчас мы ушли в небольшой оффтоп на обсуждение особенностей константных методов. Если удастся сделать красивую реализацию на спецификации шаблона с дедукцией, выложу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 13:06 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devДопустим, есть некий класс и в зависимости от того, является ли экземпляр const или non-const у этого экземпляра либо нет реализации деструктора, либо она есть. Кто как решает подобную задачу? Ты неправ, деструктор у класса есть всегда, и он всегда вызывается. Реализация при этом одна и та же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 13:38 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devegorych, есть необходимость изменить поведение экземпляра класса, когда он const, но если обычные методы можно сделать const и они будут вызываться только для const указателя/ссылки на объект, то конструкторы и деструкторы сделать const, разделив таким образом поведение при создании/разрушении, нельзя. Вот я и спрашиваю - кто и как решал подобную задачу? Ты можешь объявить два конструктора для const и не const объектов, и вызывать их соответственно. Отличать конструкторы друг от друга придётся руками (можно сделать два наследника, чтобы это было видно в названии класса). При этом ты можешь в конструкторе инициализировать некий флаг внутри класса, чтобы отличать, является ли данный экземлпяр const или не является. Ещё раз, при этом дифференцировать объекты по const|не const тебе придётся руками. Для упрощения можно ещё запрятать создание экземпляров в фабрику. P.S. да, задача идиотская, я согласен со всеми, кто так высказывался. Всё против объектной модели С++. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 13:43 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivrdb_devДопустим, есть некий класс и в зависимости от того, является ли экземпляр const или non-const у этого экземпляра либо нет реализации деструктора, либо она есть. Кто как решает подобную задачу? Ты неправ, деструктор у класса есть всегда, и он всегда вызывается. Реализация при этом одна и та же.Я знаю, что деструктор есть всегда, поэтому и написал не "нет деструктора", а "нет реализации деструктора", имея в виду ~T() {} ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 16:06 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Не отвлекайте его. Очень хочется на результат посмотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 16:18 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZiv... Отличать конструкторы друг от друга придётся руками (можно сделать два наследника, чтобы это было видно в названии класса). ... Для упрощения можно ещё запрятать создание экземпляров в фабрику. В этом случае, проблемы нет вообще. базовый класс, два наследника: TMyClassInHeap, TMyClassAsRef и просто virtual деструктор ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2018, 16:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduser, не дождешься! С дедукцией не получается, а без неё выходит банальный exactly specialized template, который даже школьник напишет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 01:51 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devРазница лишь в том, что при вызове константного метода ему прилетает константный this со всеми вытекающими.Это разница - для компилятора . Код не различает const. Я думаю, компилятор при генерации отличает ctor/dtor-ы от остальных методов. Т.е. ты не сможешь сам его позвать явно (не скомпилируется). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 05:26 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
CEMbЭто разница - для компилятора . Код не различает const. Я думаю, компилятор при генерации отличает ctor/dtor-ы от остальных методов. Т.е. ты не сможешь сам его позвать явно (не скомпилируется).Я так и написал: 21428334 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 09:30 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivТы можешь объявить два конструктора для const и не const объектов, и вызывать их соответственно. Отличать конструкторы друг от друга придётся руками (можно сделать два наследника, чтобы это было видно в названии класса). При этом ты можешь в конструкторе инициализировать некий флаг внутри класса, чтобы отличать, является ли данный экземлпяр const или не является. Ещё раз, при этом дифференцировать объекты по const|не const тебе придётся руками. Для упрощения можно ещё запрятать создание экземпляров в фабрику. P.S. да, задача идиотская, я согласен со всеми, кто так высказывался. Всё против объектной модели С++.Неа, объявить const конструктор не могу! Конструкторы и деструкторы не могут иметь cv квалификаторы. В итоге получается два точно специализированных шаблона класса-обёртки (для const и не const) к интересующему классу, плюс typedef'ы для них. Вот так - банально и скучно. Нет возможности специализировать шаблон по объявлению lvalue. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Вообще, в C++ очень много "недосказанности". К примеру: * Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 10:28 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZiv, сделал попроще: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. Объявление: Код: plaintext 1. 2. Жаль в C++ нет зарезервированного слова, позволяющего в default подставить <cv-qualifiers type> из объявления lvalue; Модератор: Будете тут какашками кидаться, выпилю обоих из форума. Не только к тебе относится. Асанизация проведена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 12:19 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devВообще, в C++ очень много "недосказанности". К примеру: * Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 13:46 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devblonduser, не дождешься! С дедукцией не получается, а без неё выходит банальный exactly specialized template, который даже школьник напишет. Ну ты всё же сильно переоцениваешь школьников. В массе они даже не знают, что такое специализация. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 13:49 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivrdb_devВообще, в C++ очень много "недосказанности". К примеру: * Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"...Ты имеешь в виду только последнее замечание или все три? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 15:44 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Мне было очень интересно увидеть, как и когда ты будешь освобождать те объекты, которые не удалил в деструкторе когда класс был объявлен как "const"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2018, 18:44 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduserМне было очень интересно увидеть, как и когда ты будешь освобождать те объекты, которые не удалил в деструкторе когда класс был объявлен как "const"?Зачем освобождать то, что не выделяется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 00:59 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devЗачем освобождать то, что не выделяется? Это следовало из твоего первого поста и из 21431824 . Обычно делают конструктор с параметрами и уже в зависимости от них либо создают мембер-объект, либо указателю присваивают NULL . В деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 12:09 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах: допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 12:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devblonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах: допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. http://cpp.sh/5aj3m Конструктор понятно как дописать ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 12:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devХорошо, поясню на пальцах: допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее?великолепная мина, с отличным, отложенным запалом )) здесь прекрасно всё))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 12:39 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devдопустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Но ты понимаешь, что указатель можно сделать не константным внутри вызова и изменить строку как угодно? Именно для строки я видел шаблон в котором реализован механизм который ты описал. Но там передаются объекты строки, а указатель на строку один. Если в какой-то момент времени строку надо изменить, то создается копия строки. При удалении последнего объекта очищается и строка. Вот такой механизм тебе не подойдет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 12:55 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
blonduserНо ты понимаешь, что указатель можно сделать не константным внутри вызова и изменить строку как угодно?Если член-указатель private, то это реализация только моя. Например: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. blonduserИменно для строки я видел шаблон в котором реализован механизм который ты описал. Но там передаются объекты строки, а указатель на строку один. Если в какой-то момент времени строку надо изменить, то создается копия строки. При удалении последнего объекта очищается и строка.Я уже думал над этим, но так как у меня в структуре не может хранится ничего, кроме одного лишь указателя, придётся сделать static переменную внутри какого-нибудь protected метода, указывающую на экземпляр std::map, который будет дополняться из конструктора (подчищаться из деструктора) и хранить указатели на экземпляры структуры с флагами инициализации, а сам метод будет возвращать состояние инициализации. Но при любой реализации есть одна загвоздка - при вызове CTest("The test message"), короткая строка может быть передана целиком в кадре стека вместе с указателем на неё и, естественно, может быть затёрта кадрами других вызовов после выхода из области видимости. Или же, может быть передан указатель на строку из кучи, а потом память из под этой строки будет освобождена. В итоге получается, что при использовании не очень больших строк, накладные расходы на отлов всех этих нюансов перекрывают выгоды от некопирования строки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 13:31 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
egorychвеликолепная мина, с отличным, отложенным запалом )) здесь прекрасно всё)))А то! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 13:32 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Siemargl, указатель внутри структуры, принципиально, только один. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 13:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devЯ уже думал над этим, но так как у меня в структуре не может хранится ничего, кроме одного лишь указателя Ну так одного указателя достаточно. Ему можно присвоить всё что угодно главное не забывать что присвоил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 13:53 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Если разнести собсно конструктор и инициализацию, то в принципе можно. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 16:56 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devSiemargl, указатель внутри структуры, принципиально, только один.Тогда придется хранить флаг константности инициализации. Но вообще то проще делать копию в любом случае, если только данных не заоблачное кол-во. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 18:06 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Еще можно использовать constexpr и вынести время жизни объекта вообще на стадию компиляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2018, 19:12 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devMasterZivпропущено... Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"...Ты имеешь в виду только последнее замечание или все три? Все три. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 11:00 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devblonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах: допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее? Твои представления об объектной модели С++ несколько проще, чем она есть на самом деле. Помимо константных и неконстантных объектов есть ещё объекты временные, и семантика перемещения, которая работает и с константными, и с неконстантными, и с временными объектами. Тебе надо ОТДЕЛЬНО, ОРТОГОНАЛЬНО К КОНСТАНТНОСТИ ОБЪЕКТА реализовать эту фичу: твой объект должен хранить либо ссылку на константу либо реальное значение, и знать, на что он ссылается в данный момент. если объект ссылается на константную строку из стат. ресурсов, то работать с ней пока объект не меняется в этом аспекте. если эта строка меняется внутри данного объекта, то менять её на ссылку на константные ресурсы либо на реальное значение. при удалении освобождать что-то только если мы храним реальное значение. И сделать это, кажется, достаточно просто, нужно хранить внутри std::variant< std::string, std::string_view > Я не знаю всю твою семантику, но похоже, что тебе это подойдёт, при этом не нужно делать почти вообще ничего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 11:20 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivВсе три.Давай по пунктам? * Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; Зачем возможность писать const, если при создании экземпляра класса в куче этот const, ровным счётом, ни на что не влияет? * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; При размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно: Код: plaintext 1. 2. Так почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение. * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; Есть же using, которые используются подобно typedef! Так почему бы не предусмотреть в них использование cv-квалификаторов c помощью какой-нибудь подходящей семантики? Что-то типа: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 11:52 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivТвои представления об объектной модели С++ несколько проще, чем она есть на самом деле. Помимо константных и неконстантных объектов есть ещё объекты временные, и семантика перемещения, которая работает и с константными, и с неконстантными, и с временными объектами. Тебе надо ОТДЕЛЬНО, ОРТОГОНАЛЬНО К КОНСТАНТНОСТИ ОБЪЕКТА реализовать эту фичу: твой объект должен хранить либо ссылку на константу либо реальное значение, и знать, на что он ссылается в данный момент. если объект ссылается на константную строку из стат. ресурсов, то работать с ней пока объект не меняется в этом аспекте. если эта строка меняется внутри данного объекта, то менять её на ссылку на константные ресурсы либо на реальное значение. при удалении освобождать что-то только если мы храним реальное значение. И сделать это, кажется, достаточно просто, нужно хранить внутри std::variant< std::string, std::string_view > Я не знаю всю твою семантику, но похоже, что тебе это подойдёт, при этом не нужно делать почти вообще ничего. Я, пока что, отказался от мысли реализовать эту бредовую идею прямо сейчас, но для себя решил плясать от обратного - если константное значение находится в памяти модуля процесса и выделенная под него память read-only, то инициализировать без копирования и хранить этот признак в std::map, на который будет указывать статический указатель внутри protected виртуального метода. Просто сейчас лень штудировать MSDN на предмет всех этих плясок вокруг получения информации о страницах памяти модуля, так как сейчас нет крайней необходимости работы с большими строками или блобами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 11:59 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно : Код: plaintext 1. 2. Спасибо, поржал ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 12:10 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZСпасибо, поржал На , еще поржи! :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 12:25 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно ... Спасибо, поржал Или ты мне хочешь рассказать, как компилятор вставляет машинный код, оперирующий регистрами (R/E)SP и (R/E)BP? Не стОит!... Ровно тоже самое делает функция _malloca. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 13:12 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devИли ты мне хочешь рассказать, как компилятор вставляет машинный код, оперирующий регистрами (R/E)SP и (R/E)BP? Не стОит!... Ровно тоже самое делает функция _malloca. Расскажи-ка тогда, почему при /O2 кода больше с alloca? Код здорового человека Код: plaintext 1. 2. 3. 4. 5. 6. 7. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Против Код курильщика Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 13:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, какая, в данном случае разница, больше кода или меньше или откуда берётся код, выделяющий память на стеке - из библиотечной функции, встроенной функции или, собственно, вставляется компилятором? Речь идёт о ПРИНЦИПАХ размещения и инициализации экземпляра класса на стеке. Нафига тут твои детали, которые к этим принципам никакого прямого отношения не имеют? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 13:58 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devNekZ, какая, в данном случае разница, больше кода или меньше или откуда берётся код, выделяющий память на стеке - из библиотечной функции, встроенной функции или, собственно, вставляется компилятором? Речь идёт о ПРИНЦИПАХ размещения и инициализации экземпляра класса на стеке. Нафига тут твои детали, которые к этим принципам никакого прямого отношения не имеют? Точно того ты мог добиться безо всяких аллокаов Код: plaintext 1. 2. 3. Сдаётся мне, ты просто хочешь поспорить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 14:06 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZТочно того ты мог добиться безо всяких аллокаов Код: plaintext 1. 2. 3. Сдаётся мне, ты просто хочешь поспорить.Мог! И что дальше? Речь не о способе выделения памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 14:19 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
* Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; Оператор NEW выделяет память под объект. Как думаешь, памяти всё равно, какой объект в ней лежит, изменяемый или нет? Всё равно. Должен operator new зависеть от константности объекта, под который выделяется память ? Нет, не должен. авторЗачем возможность писать const, если при создании экземпляра класса в куче этот const, ровным счётом, ни на что не влияет? Ты сможешь этот объект привязать только к константной ссылке или константному указателю , и объект после создания не будет меняться. * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; placement new -- это способ вызвать конструтор и осуществить инициализацию нового объекта в данной памяти. Создание объекта состоит из двух фаз: выделяется память под объект каким-либо образом в этой памяти инициализируется новый объект с помощью вызова конструктора. На стеке (auto память) это происходит так: выделяется память под объект путём резервирования места определённого объёма в стеке. с помощью вызова конструктора там инициализируется объект. placement new делает РОВНО второй пункт этого плана, т.е. при создании объекта на стеке именно как раз "эмулируется placement new", так что что тебе ещё надо от С++, не понятно. * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; При создании объекта и удалении объекта объект должен быть изменён, в этом суть инициализации. Объект сначала находится в неинициализированном состоянии, вызывается конструктор, и содержимое объекта меняется таким образом, что объект находится уже в инициализированном состоянии. Ключевое тут -- что меняется. ЭТо значит, что не смотря ни на какие квалификаторы, используемые при определении нового объекта, он ОБЯЗАН поменяться. Т.е. квалификаторы не должны и не могут работать в конструкторе. То же самое можно сказать и про разрушение объекта и деструктор. Ну и на самом деле (если подумать) квалификаторами обладают не сами объекты, а ссылки на них (в любом виде). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно : Код: plaintext 1. 2. Спасибо, поржал Не, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:38 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНа стеке (auto память) это происходит так: выделяется память под объект путём резервирования места определённого объёма в стеке. с помощью вызова конструктора там инициализируется объект. placement new делает РОВНО второй пункт этого плана, т.е. при создании объекта на стеке именно как раз "эмулируется placement new", так что что тебе ещё надо от С++, не понятно. В моем понимании, "эмуляция placement new" это когда компилятор создает код вызова placement new независимо от того, создана ли реализация этого оператора компилятором по умолчанию (по моему, она до сих пор не создается по умолчанию и компилятор инициализирует экземпляр на стеке просто пиная конструктор) или же разработчик сделал эту реализацию самостоятельно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:49 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНе, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. Ну как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами. Перед вызовом call передвигается sp на размер фрейма вниз, в то время как вызов аллоки двигает sp вниз уже внутри самой функции, т.е. после call и выполняет кучу ненужной работы, так как размер известен на этапе компиляции, поэтому столько кода и нагенерилось ненужного. По той же логике можно точно так же сказать что удаление гланд через ж0пу и через рот -- вещи равнозначные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:55 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZНу как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами.Я не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 18:04 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devЯ не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. Разве ты не понял в чём суть? В этом. rdb_devТак почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение. Ещё раз смотрим в код здорового человека и не видим там operator new, в отличие от нижележащего. Компилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным. P.S. Забавно, что clang с этим примером справляется лучше VS'а. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 18:31 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZКомпилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным.То есть компилятор не формирует код для расширения кадра стека при объявлении там экземпляра класса? Это делает конструктор объекта? Фактически мы всё равно имеем "отдельные фазы" - отдельно расширение кадра стека и отдельно вызов конструктора, точно также, как отдельные фазы оператора new - отдельно выделение памяти из кучи и отдельно вызов конструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2018, 23:41 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devТо есть компилятор не формирует код для расширения кадра стека при объявлении там экземпляра класса? Это делает конструктор объекта? Формирует, так и есть. rdb_devФактически мы всё равно имеем "отдельные фазы" - отдельно расширение кадра стека и отдельно вызов конструктора, точно также, как отдельные фазы оператора new - отдельно выделение памяти из кучи и отдельно вызов конструктора. А вот здесь не факт, ведь если бы ты попробовал посмотреть что делают clang или gcc с тем же кодом: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 08:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, какая разница, как выглядит вызов, если точкой возврата всё равно будет адрес, запихнутый в стек крайним перед передачей управления на первую команду конструктора или чего-то там еще? Ты можешь вызвать привычно через call, запихать адрес возврата и пнуть через jmp, а можешь извратится, запихать в стек адрес, на который хочешь передать управление и сделать ret. В чем разница-то? Принципиально мы всё равно имеет два этапа - выделение памяти и вызов конструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 19:56 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_dev, Да, два этапа, только если компилятор считает, что не нужно делать никакого call'а, он не будет его делать Код: plaintext 1. 2. 3. 4. 5. 6. 7. clang и gcc сжали это в Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 23:20 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_dev, Да, два этапа, только если компилятор считает, что не нужно делать никакого call'а, он не будет его делать [src c++] struct MyClass{ int x; MyClass() { x = rand(); } int f() { return x; } }; int main() { MyClass b; return b.f(); } clang и gcc сжали это в Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 09:12 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devС чего ты взял, что перед вызовом jmp на стеке нет адреса возврата из main, который позволяет, в данном случае, делать ret из метода MyClass::f() прямо в точку вызова main возвращая тот же int? Глянь-ка отладчиком! С того, что я привык верить своим глазам. И та заглушка, которая была добавлена линковщиком (аля _start) в счёт не идёт, тупой редирект на другую функцию и больше ничего. Совсем ничего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 09:46 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devС чего ты взял, что перед вызовом jmp на стеке нет адреса возврата из main, который позволяет, в данном случае, делать ret из метода MyClass::f() прямо в точку вызова main возвращая тот же int? Глянь-ка отладчиком! С того, что я привык верить своим глазам. И та заглушка, которая была добавлена линковщиком (аля _start) в счёт не идёт, тупой редирект на другую функцию и больше ничего. Совсем ничего.Конечно тупой редирект! Что же еще? Если функция возвращает тот же самый тип и является результатом main, то из main будет именно тупой "редирект" на MyClass::f(), так как адрес возврата из main уже на стеке, которым и воспользуется ret внутри f(), чтобы вернуть значение main в точку вызова. Это оптимизация данного конкретного случая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 10:38 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, хотя, скорее всего, адрес в jmp указывает непосредственно на библиотечную функцию rand(), а не на MyClass::f(). Компилятор решил, что в данном случае ни экземпляр MyClass, ни его метод f() вообще не нужны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:10 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devКонечно тупой редирект! Что же еще? Если функция возвращает тот же самый тип и является результатом main, то из main будет именно тупой "редирект" на MyClass::f(), так как адрес возврата из main уже на стеке, которым и воспользуется ret внутри f(), чтобы вернуть значение main в точку вызова. Это оптимизация данного конкретного случая. Да, пример чисто академический, и именно наличие вот таких вот случаев показывает, что именно компилятор сам решает что где и как рассматривать, на какие фазы разбивать такие-то операции с объектами, а в каких случаях можно всё заинлайнить, не добавляя лишний вызов, в каких случаях вообще всё выбросить как dead code и т.д. Такие решения принимаются в том числе ещё и на основе целевой архитектуры и многих других факторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:35 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devNekZ, хотя, скорее всего, адрес в jmp указывает непосредственно на библиотечную функцию rand(), а не на MyClass::f(). Компилятор решил, что в данном случае ни экземпляр MyClass, ни его метод f() вообще не нужны. Я до тебя это и пытаюсь донести. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devВ моем понимании, "эмуляция placement new" это когда компилятор создает код вызова placement new независимо от того, создана ли реализация этого оператора компилятором по умолчанию (по моему, она до сих пор не создается по умолчанию и компилятор инициализирует экземпляр на стеке просто пиная конструктор) или же разработчик сделал эту реализацию самостоятельно. 0) placement new не переопределяется. 1) код placement new -- это вызов констуктора с указанным placement-у указателем на память в виде this . 2) соответственно, код placement new всегда инлайнится. Это собственно один вызов функции. Что тебе ещё надо эмулировать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:14 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZMasterZivНе, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. Ну как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами. Перед вызовом call передвигается sp на размер фрейма вниз, в то время как вызов аллоки двигает sp вниз уже внутри самой функции, т.е. после call и выполняет кучу ненужной работы, так как размер известен на этапе компиляции, поэтому столько кода и нагенерилось ненужного. По той же логике можно точно так же сказать что удаление гланд через ж0пу и через рот -- вещи равнозначные. Что то ты тут намутил. Он всё там вполне адекватно расписал и дал эквивалентный код. Другое дело, что код этот нафиг не нужен, поскольку можно просто написать автоматическую переменную этого класса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:16 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devЯ не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. Разве ты не понял в чём суть? В этом. rdb_devТак почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение. Ещё раз смотрим в код здорового человека и не видим там operator new, в отличие от нижележащего. Компилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным. P.S. Забавно, что clang с этим примером справляется лучше VS'а. Ещё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivЕщё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. Я об этом ниже написал, переходя от голой теории к конкретике. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZMasterZivЕщё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. Я об этом ниже написал, переходя от голой теории к конкретике. Ну и? Топик закрываю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНу и? Топик закрываю? ТСу решать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 14:14 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZMasterZivЕщё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. Я об этом ниже написал, переходя от голой теории к конкретике.Если переходить к конкретике, то в твоём примере никакой экземпляр класса вообще не создается - нигде, а компилятор на -O3 заменяет метод объекта и его член-переменную функциональным эквивалентом, т.е., просто фигачит jmp на rand() из main. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:05 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНу и? Топик закрываю?В общем-то, перетёрли уже всё, что только можно было перетереть и "в" и "около". Закрывай, коль надоела эта байда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:07 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devЕсли переходить к конкретике, то в твоём примере никакой экземпляр класса вообще не создается - нигде, а компилятор на -O3 заменяет метод объекта и его член-переменную функциональным эквивалентом, т.е., просто фигачит jmp на rand() из main. Хе-хе, так в том-то и была суть всего, что я тебе талдычу уже третью страницу топика. Да даже на -O1 останется лишь jmp. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:09 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZХе-хе, так в том-то и была суть всего, что я тебе талдычу уже третью страницу топика. Да даже на -O1 останется лишь jmp.Told'ычить-то ты, конечно, told'ычишь, но объекта как не было, так и нет, а мы говорим именно об объектах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:18 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZiv0) placement new не переопределяется. 1) код placement new -- это вызов констуктора с указанным placement-у указателем на память в виде this . 2) соответственно, код placement new всегда инлайнится. Это собственно один вызов функции.Да брось! Всё прекрасно переопределяется: Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:21 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devTold'ычить-то ты, конечно, told'ычишь, но объекта как не было, так и нет, а мы говорим именно об объектах. В терминал языка ассемблера вообще объектов нет, это чисто тот удобный фасад для программистов чтобы они не видели всю поднаготную. И именно такие вот оптимизации, выкидывающие вообще всякие там упоминания о твоём классе и его мемберах из итогового ассемблера, демонстрируют тебе, что нет никаких фаз выделения памяти на стеке и вызова placement new , они существуют только в твоём сознании. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:39 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, В терминах* ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 16:39 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZВ терминал языка ассемблера вообще объектов нет, это чисто тот удобный фасад для программистов чтобы они не видели всю поднаготную.Объектов нет не в терминах ассемблера, а в терминах машинных кодов, а в терминах ассемблера он вполне себе существует и, причем, с виртуальными методами. Например, в TASM. NekZИ именно такие вот оптимизации, выкидывающие вообще всякие там упоминания о твоём классе и его мемберах из итогового ассемблера, демонстрируют тебе, что нет никаких фаз выделения памяти на стеке и вызова placement new , они существуют только в твоём сознании.Да что ты говоришь? Попробуй-ка при при максимальной оптимизации добавить квалификатор volatile к объявлению метода MyClass::f*(), к объявлению экземпляра класса собери и удивись "силе моего сознания". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 19:45 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devДа что ты говоришь? Попробуй-ка при при максимальной оптимизации добавить квалификатор volatile к объявлению метода MyClass::f*(), к объявлению экземпляра класса собери и удивись "силе моего сознания". Давай. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. clang -O3 Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 19:56 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZГде выделение памяти под объект? push rax ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 20:09 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevNekZГде выделение памяти под объект? push rax ? Нет, это пушится адрес возврата для последующей инструкции call ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 20:15 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZНет, это пушится адрес возврата для последующей инструкции callЛеонид абсолютно прав! "push rax" расширяет стек вниз на 8 байт, сохраняя там значение из "rax", что равносильно (в нотации Intel): Код: asm 1. 2. Обычно, компилятор примерно так и делает, но в данном, конкретном случае, расширение кадра невелико и компилятор, почему-то, выбрал "push rax" с инициализацией памяти на стеке из регистра "rax", вместо "sub rsp, 8" без инициализации. Далее, по соглашению __cdecl, результат функции rand() помещается в регистр "eax" и мнемоника "mov dword ptr [rsp + 4], eax" указывает нам на то, что значение из регистра "eax" помещается, в старшее двойное слово расширенной части кадра стека. Сие нам говорит о том, что компилятор разместил код, расширяющий кадр стека с выравниванием на четверное слово, но, при этом, используется только старшее двойное слово - "MyClass::x", а мнемоника "mov eax, dword ptr [rsp + 4]" говорит нам о том, что в clang квалификатор volatile напрочь отключает оптимизацию, как таковую, чего не происходит, например, в гнусе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 21:11 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_dev, Да, что-то я забыл совсем, что о адресе возврата уже call сам заботится. Это если jmp юзать для вызова в новом кадре, то потребуются push и pop. А вот, кстати и ответ wikipediaSince GCC version 4.5, the stack must be aligned to a 16-byte boundary when calling a function (previous versions only required a 4-byte alignment.) push используется для CPU со stack engine как и последующие два mov'а, типа так более эффективно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 21:50 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, только мне непонятно зачем делать push/pop, когда после любой операции модификации "rsp" для выравнивания вполне достаточно сделать "and rsp, -16". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2018, 00:05 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Чтобы немного разбавить офтопик, небольшая ссылка по теме :) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0847r0.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2018, 01:19 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, если я правильно понимаю написанное, парни предлагают различать то, через что осуществляется доступ к членам/методам экземпляра класса (объекта) - через lvalue-ссылку или же через rvalue-ссылку с учётом cv-квалификаторов, а также использовать "this" в объявлении параметров метода в качестве ключевого слова для указания того, что дедукция шаблона должна осуществляться по типу lvalue/rvalue ссылки, через которую осуществляется доступ и, опять же, с учётом cv-квалификаторов. Похоже, я не одинок в своих хотелках! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2018, 10:40 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devпредлагают различать то, через что осуществляется доступ к членам/методам экземпляра класса (объекта) - через lvalue-ссылку или же через rvalue-ссылку с учётом cv-квалификаторов Это уже есть начиная с С++11. А остальное - да, предлагают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2018, 11:37 |
|
||
|
|

start [/forum/topic.php?all=1&fid=57&tid=2017848]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
48ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
104ms |
get tp. blocked users: |
2ms |
| others: | 11ms |
| total: | 213ms |

| 0 / 0 |
