Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Коллеги помогите пожалуйста Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Есть вот такой код Результат - вот такая печать created released finished released Подскажите как сделать так чтобы деструктор (released) не вызывался 2 раза - это же вроде как некорректно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 12:08 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semen, у тебя для каждого экземпляра test деструктор вызывается единожды - для экземпляра в map и для экземпляра на стеке (test t). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 12:16 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Как это я же создаю 1 объект test t{}; и кладу его в мап ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 12:18 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenКак это я же создаю 1 объект test t{}; и кладу его в мап 1) создаёшь экземпляр где? 2) глагол "кладу" - расшифруй для себя (можно глняуть отладчиком что происходит, только с заходом в саму мапу) именно про это те и сказали выше. (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 12:28 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
test t{}; Создаю на стеке aMap->emplace(s, t); Неужели конструктор копирования вызывается ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 12:30 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semen, а как же?! Если ты явно не указал на отсутствие реализации конструктора копирования, он будет создан по умолчанию с реализацией простого копирования байт-в-байт. И вообще - создавать на стеке экземпляры класса, а потом помещать их в map, созданный в куче - моветон. Делай так: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:01 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Я маленько наврал. :) Метод emplace принимает ссылки на rvalue: Код: plaintext 1. 2. Поэтому, надо делать что-то типа: Код: plaintext 1. В этом случае, на стеке будет создан временный экземпляр класса test, а при передаче в map будет задействован либо конструктор копии, либо конструктор пересылки, в зависимости от того, реализованы ли эти конструкторы для класса. Это то, о чем писалось в другой ветке - RVO/NRVO. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:24 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenКоллеги помогите пожалуйста Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Есть вот такой код Результат - вот такая печать created released finished released Подскажите как сделать так чтобы деструктор (released) не вызывался 2 раза - это же вроде как некорректно У тебя всё нормально с деструкторами. У тебя ненормально с конструкторами. Ты не всех их "трассируешь". У тебя в коде вызывается MOVE-конструктор, который ты не замечаешь, игнорируешь, а потом думаешь (неверно), что деструктор вызывается лишний раз. http://en.cppreference.com/w/cpp/container/map/emplace ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:28 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.sementest t{}; Создаю на стеке aMap->emplace(s, t); Неужели конструктор копирования вызывается ? Ну да, или он. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:29 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devsemen.s.semen, а как же?! Если ты явно не указал на отсутствие реализации конструктора копирования, он будет создан по умолчанию с реализацией простого копирования байт-в-байт. И вообще - создавать на стеке экземпляры класса, а потом помещать их в map, созданный в куче - моветон. Делай так: Код: plaintext 1. Ты хотел написать НЕ ДЕЛАЙ так ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:29 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devsemen.s.semen, а как же?! Если ты явно не указал на отсутствие реализации конструктора копирования, он будет создан по умолчанию с реализацией простого копирования байт-в-байт. Нет, implicit конструкторы копирования ничего не копируют байт-в байт. Это -- расхожий среди новичков миф о С++. Дефолтный конструктор копирования вызывает копирование предков, затем почленное копирование всех мемберов. Никакого копирования байт-в байт не происходит никогда. авторИ вообще - создавать на стеке экземпляры класса, а потом помещать их в map, созданный в куче - моветон. Не выдумывай ерунду. Ты не на Java пишешь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:32 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semen, А зачем вообще map создавать в куче? Если уж создал, то и подчистить за собой надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:53 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZiv, ненаследованные (собственные) члены конструктор копирования по умолчанию может и обычным копированием сделать через MOVSB, задав в регистрах #SI и #DI источник и приемник соответственно, а в регистре #CX - кол-во байт. Конечно, зависит от конкретной реализации компилятора. Кстати, обращал внимание, как сейчас компиляторы помещают в стек параметры? Никаких тебе множественных PUSH! :) Сразу грузит в #SP значение с учётом смещения для всех параметров, формируя кадр стека и помещает туда параметры обычным MOV. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:58 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZivТы хотел написать НЕ ДЕЛАЙ так ?Я чуть ниже исправился. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 13:58 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZivУ тебя в коде вызывается MOVE-конструктор, который ты не замечаешь, игнорируешь, а потом думаешь (неверно), что деструктор вызывается лишний раз.Конструктор пересылки, в отличие от конструктора копии, не создается по умолчанию - необходима явная реализация. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 14:01 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenПодскажите как сделать так чтобы деструктор (released) не вызывался 2 раза - это же вроде как некорректно Код: 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. Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 14:35 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
AmKadsemen.s.semenПодскажите как сделать так чтобы деструктор (released) не вызывался 2 раза - это же вроде как некорректно Код: 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. Код: plaintext 1. 2. Интересно А в данном случае std::move(t) не приведет к вызову конструктора и созданию еще одного объекта ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 14:48 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devMasterZiv, ненаследованные (собственные) члены конструктор копирования по умолчанию может и обычным копированием сделать через MOVSB, задав в регистрах #SI и #DI источник и приемник соответственно, а в регистре #CX - кол-во байт. Конечно, зависит от конкретной реализации компилятора. Кстати, обращал внимание, как сейчас компиляторы помещают в стек параметры? Никаких тебе множественных PUSH! :) Сразу грузит в #SP значение с учётом смещения для всех параметров, формируя кадр стека и помещает туда параметры обычным MOV. Почему ты выдумываешь всё время? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:03 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devMasterZivУ тебя в коде вызывается MOVE-конструктор, который ты не замечаешь, игнорируешь, а потом думаешь (неверно), что деструктор вызывается лишний раз.Конструктор пересылки, в отличие от конструктора копии, не создается по умолчанию - необходима явная реализация. Опять фантазии? Он В ДАННОМ КОНКРЕТНОМ случае не создаётся, потому что деструктор объявлен. Да, это я прошляпил. Тогда должен использоваться конструктор копирования (который есть всегда если move не объявишь). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:07 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_dev, в этой книжке Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 написано как устроен std::move. Он "работает" во время компиляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:08 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenА в данном случае std::move(t) не приведет к вызову конструктора и созданию еще одного объекта ? std::move вообще ничего не делает. Как он может создавать объект? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:09 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Dima Trdb_dev, в этой книжке Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 написано как устроен std::move. Он "работает" во время компиляции. Он просто ссылку преобразует в rvalue-ссылку, если это возможно. И всё. А далее что-то либо копирует из rvalue-ссылки, либо перемещает. Как может. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:11 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenА в данном случае std::move(t) не приведет к вызову конструктора и созданию еще одного объекта ?Нет. Происходит передача указателя на уже выделенный участог памяти. После передачи указателя ф-ия main им уже не владеет. Исключительные права передаются map-объекту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:12 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
AmKadsemen.s.semenА в данном случае std::move(t) не приведет к вызову конструктора и созданию еще одного объекта ?Нет. Происходит передача указателя на уже выделенный участог памяти. После передачи указателя ф-ия main им уже не владеет. Исключительные права передаются map-объекту. И зачем ты туда new всобачил? Чтобы запутать ещё больше? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:17 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZivAmKadпропущено... Нет. Происходит передача указателя на уже выделенный участог памяти. После передачи указателя ф-ия main им уже не владеет. Исключительные права передаются map-объекту. И зачем ты туда new всобачил? Чтобы запутать ещё больше? Уважаемый Мастер Зив Привидите пожалуйста Ваш корректно работающий вариант кода с использованием std::move ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:18 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZivDima Trdb_dev, в этой книжке Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 написано как устроен std::move. Он "работает" во время компиляции. Он просто ссылку преобразует в rvalue-ссылку, если это возможно.Мне больше нравится, как сказано у самого Мейерса: std::move преобразует в rvalue (без "-ссылку"). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:20 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
semen.s.semenПривидите пожалуйста Ваш корректно работающий вариант кода с использованием std::move ИМХО лучше почитай об этом в книге Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 Там понятным языком разжевано что такое std::move и что надо прописать в классе чтобы он работал. Читать немного, 10-20 страниц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:25 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
MasterZivИ зачем ты туда new всобачил? Чтобы запутать ещё больше?Не понял вопроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 15:27 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Dima Trdb_dev, в этой книжке Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 написано как устроен std::move. Он "работает" во время компиляции.Как еще должен "работать" обычный шаблон, как не во время компиляции? И причем тут, вообще, шаблон std::move? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2018, 16:32 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devненаследованные (собственные) члены конструктор копирования по умолчанию может и обычным копированием сделать через MOVSB, задав в регистрах #SI и #DI источник и приемник соответственно НЕ НАДО так делать! В случае с копированием двух объектов одного класса может быт ещё ничего плохого не произойдёт, но в общем случае можно закосячить объект. Во-первых, в объект входит указатель на виртуальную таблицу методов, если есть (это MS) Во-вторых, если есть родительские методы, то &x и реальное начало данных x могут отличаться. Плюс ещё оптимизатор, вроде, может чего-нить местами переставить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2018, 05:28 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
CEMbВо-первых, в объект входит указатель на виртуальную таблицу методов, если есть (это MS) Плюс ещё оптимизатор, вроде, может чего-нить местами переставить.Собственно, указатель this, это указатель на указатель на таблицу виртуальных методов - это еще в Borland TASM было. CEMbВо-вторых, если есть родительские методы, то &x и реальное начало данных могут отличаться.Не может! У экземпляра класса есть лишь одна таблица виртуальных методов, которая хранится отдельно от экземпляра класса и все экземпляры одного и того же класса имеют один и тот же указатель на таблицу виртуальных методов. При наследовании, компилятор создает копию родительской таблицы виртуальных методов и добавляет в конец этой копии указатели на виртуальные методы наследника в порядке их объявления. Конец таблицы виртуальных методов определяется указателем NULL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2018, 09:43 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_dev, ну, может на счёт второго я и напутал что-то, я не смог вспомнить пример. Но первого достаточно, чтобы не копировать память вручную. Это потенциальная ошибка, у тебя могут быть пара указателей на класс А, один из которых на самом деле указывает на дочерний класс В. В случае прямого копирования получится неправильный экземпляр. Хотя, интересный хак получается :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 05:15 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
CEMbrdb_dev, ну, может на счёт второго я и напутал что-то, я не смог вспомнить пример. Но первого достаточно, чтобы не копировать память вручную. Это потенциальная ошибка, у тебя могут быть пара указателей на класс А, один из которых на самом деле указывает на дочерний класс В. В случае прямого копирования получится неправильный экземпляр. Хотя, интересный хак получается :)Почему должен получится неправильный экземпляр? Давай рассмотрим простой пример: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. В соответствии с ABI, экземпляр B в памяти будет выглядеть следующим образом (на x86_32 при выравнивании на QWORD): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Поэтому, конструктор копии экземпляра A скопирует именно ту часть, которую должен. Вообще, я предпочитаю объединять члены класса в структуру - так проще копировать, если нет необходимости делать копии того, на что указывают члены-указатели, а для конструктора пересылки это идеальный вариант. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 09:42 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Недавно обсуждали что std::string нельзя просто скопировать для переноса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 09:56 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
Dima T, конечно, экземпляры чужих классов нехорошо просто копировать, особенно, если не знаешь как они устроены, это ежу понятно! Но создать реализацию конструктора пересылки своего класса, которая будет копировать данные байт-в-байт, а затем подчищать источник - вполне допустимо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 10:23 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
rdb_devПочему должен получится неправильный экземпляр?потому что vtable pointer от одного класса перезапишется поверх vtp другого класса. Если использовать this-ы. rdb_devДавай рассмотрим простой пример:а, ты какой хитрый! ты берёшь адрес с переменной. а это ещё хуже, потому что напишешь копировальщик. А потом забудешь, будешь рефакторить и перед a1 поставишь какую-нить другую переменную - и получится трудноуловимая ошибка. Нет, я согласен, так делать можно при должной осторожности . Но я бы лично так не делал. Выгода не понятна, сомневаюсь в наличии таких классов, у которых movsb даст много выигрыша по сравнению с по-переменным копированием. Если в классе есть большие блоки данных (массивы, векторы), у них свой копировальщик. Все остальные копируются вручную. Кстати, а что будет, если shared_ptr так скопировать? Т.е. понятно, что счётчик не увеличится, но что будет когда объект класса содержащего копию этого shared_ptr будет уничтожен? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 11:11 |
|
||
|
2 раза вызывается деструктор
|
|||
|---|---|---|---|
|
#18+
CEMbпотому что vtable pointer от одного класса перезапишется поверх vtp другого класса. Если использовать this-ы.Естественно, копировать указатель на таблицу виртуальных методов не стОит! Он и так нормально проинициализируется. CEMbа, ты какой хитрый! ты берёшь адрес с переменной.Конечно! Что же еще? 😊 CEMbа это ещё хуже, потому что напишешь копировальщик. А потом забудешь, будешь рефакторить и перед a1 поставишь какую-нить другую переменную - и получится трудноуловимая ошибка.Поэтому, я и написал, что предпочитаю засовывать всё мемберы в инкапсулируемую структуру. Её проще копировать и даже можно написать inline конструктор копии или конструктор пересылки такой структуры. CEMbНет, я согласен, так делать можно при должной осторожности . Но я бы лично так не делал. Выгода не понятна, сомневаюсь в наличии таких классов, у которых movsb даст много выигрыша по сравнению с по-переменным копированием. Если в классе есть большие блоки данных (массивы, векторы), у них свой копировальщик. Все остальные копируются вручную.Представь, что у тебя не три и не четыре члена, размером не более размерности регистра платформы, которые компилятор может распихать в регистры EAX, EDX, ECX, EBX, а гораздо больше и, к примеру, все long long, а приложение 32-х разрядное. Я пихаю все члены в структуру, чтобы не пропустить в конструкторе копии или пересылки какой-нибудь член, а гарантировано всё скопировать. Для конструктора пересылки это вполне нормальный подход, так как после копирования можно просто заполнить структуру источника нолями, что позволит обнулить и указатели, чтобы деструктор не освободил данные, которыми уже владеет объект-приемник. CEMbКстати, а что будет, если shared_ptr так скопировать? Т.е. понятно, что счётчик не увеличится, но что будет когда объект класса содержащего копию этого shared_ptr будет уничтожен?Не надо просто копировать shared_ptr - он на это не расчитан. Другое дело, если ты создаешь свой собственный класс safe-thread смарт-указателя и чтобы при возврате его как rvalue через стек не дёргать каждый раз переменную подсчёта ссылок в синглетоне через медленные атомарные операции работы с памятью, ты можешь написать конструктор пересылки, который будет лишь копировать данные из источника и обнулять источник. Но это при условии, что синглетон типа не содержит реализацию реферальных ссылок на смарт-указатели. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2018, 12:18 |
|
||
|
|

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

| 0 / 0 |
