Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#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. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. Пытаюсь сделать сообщение полноценным объектом. Вызвать конструктор не проблема, проблема с деструктором. Проблема в том что память под сообщением очищается библиотекой, а для нее содержимое это void*, как тут быть с деструктором? Может как-то можно извернуться на шаблонах и адрес деструктора изначально сохранить при создании сообщения в create<T>(), а в erase() просто его вызвать? Может еще какие-то способы есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 16:44 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima T, Или крестик снять или трусы надеть. Либо ты делаешь полноценный объект с виртуальным деструктором либо типизированный обработчик на шаблонах (можно чтобы базовый <Т> умел удалять всё содержимое единым куском). Есть еще подвариант - память под сообщение выделять одним цельным куском и удалится оно средствами аллокатора. Тогда никаких конструкторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 20:13 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima TМожет как-то можно извернуться на шаблонах и адрес деструктора изначально сохранить при создании сообщения в create<T>(), а в erase() просто его вызвать? Можно конечно. Сделайте вместо шаблонных функций шаблонный класс со статическими методами, и в нем же функцию очистки, вызывающую деструктор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 20:48 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
SiemarglDima T, Или крестик снять или трусы надеть. Я и то и другое готов сделать, только как? SiemarglЛибо ты делаешь полноценный объект с виртуальным деструктором либо типизированный обработчик на шаблонах (можно чтобы базовый <Т> умел удалять всё содержимое единым куском). Есть еще подвариант - память под сообщение выделять одним цельным куском и удалится оно средствами аллокатора. Тогда никаких конструкторов. Я гоняю сообщения, точнее указатели на них, между обработчиками сообщений, причем типы мне неизвестны, я либа, но часть этой либы это удаление сообщений, т.е. освобождение памяти. Типизацию я сделал c помощью контроля typeid(T).hash_code(), который в сообщение пишется при создании. Сделать полноценные типизированные сообщения вообще не вариант: один обработчик может получать несколько типов сообщений. Для либы без разницы какие типы, главное доставить их в порядке отправления, т.е. очередь из разных типов. Можно конечно классическое наследование, т.е. базовый класс my_msg_t и гонять указатель на него, но я тут теряю простоту написания кода, я не смогу сделать сообщение из std::string или std::vector, я буду вынужден объявить класс производный от my_msg_t где внутри будет std::string. Кроме лишних букав в коде это еще лишний тормоз в виде вызова виртуальных методов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 21:04 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
В общем мне надо кривой костыль, который будет быстро и надежно работать внутри либы. А снаружи все будет чопорно и по фэншую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 21:34 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima T, >еще лишний тормоз в виде вызова виртуальных методов. Это одна ассемблерная инструкция. Это не тормоз ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 00:15 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
ДмитрийСделать полноценные типизированные сообщения вообще не вариант: один обработчик может получать несколько типов сообщений. Для либы без разницы какие типы, главное доставить их в порядке отправления, т.е. очередь из разных типов. Можно конечно классическое наследование, т.е. базовый класс my_msg_t и гонять указатель на него, но я тут теряю простоту написания кода, я не смогу сделать сообщение из std::string или std::vector, я буду вынужден объявить класс производный от my_msg_t где внутри будет std::string. Кроме лишних букав в коде это еще лишний тормоз в виде вызова виртуальных методов. Мне кажется, что нужно создать базовый класс-обертку, который и будет содержать всю необходимую информацию. И виртуальные функции здесь пригодятся. Собственно то, что ты и написал выше. Только ты почему-то рассуждаешь в таком формате, словно это будет избыточным, но по-моему это так не выглядит)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 00:55 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
BarloneDima TМожет как-то можно извернуться на шаблонах и адрес деструктора изначально сохранить при создании сообщения в create<T>(), а в erase() просто его вызвать? Можно конечно. Сделайте вместо шаблонных функций шаблонный класс со статическими методами, и в нем же функцию очистки, вызывающую деструктор. Как же это правильно называется, это уже давно планируют добавить в стандарт.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 00:56 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima T Может еще какие-то способы есть? в таких случаях самое правильное -вызвать деструктор руками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 01:34 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#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. 28. 29. 30. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 08:19 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
SashaMercuryМне кажется, что нужно создать базовый класс-обертку, который и будет содержать всю необходимую информацию. И виртуальные функции здесь пригодятся. Собственно то, что ты и написал выше. Только ты почему-то рассуждаешь в таком формате, словно это будет избыточным, но по-моему это так не выглядит)) Я к С привык, в С++ слабо разбираюсь, но кое-что оттуда надо, например STD. Наверно поэтому :) Прикинул, букав действительно не намного больше. Можно затестить с оберткой, тем более там виртуальных функций особо не надо вызывать, их там нет, msg_t это структура. Тогда возникает следующий вопрос: если я перегружу new для базового класса (msg_t), то будет ли он вызываться при создании объекта дочернего класса? Я хочу простенький менеджер памяти добавить, т.е. не освобождать память сразу, а откладывать указатель в кэш и при следующем создании сообщения такого же размера просто выдавать из кэша. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 09:03 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima TМожно затестить с оберткой, тем более там виртуальных функций особо не надо вызывать, их там нет, msg_t это структура. msg->free - это и есть виртуальная функция )) Код: plaintext 1. 2. 3. 4. 5. 6. Так и надо делать. Это называется type erasure. То же самое делают всякие std::function, std::shared_ptr Dima TТогда возникает следующий вопрос: если я перегружу new для базового класса (msg_t), то будет ли он вызываться при создании объекта дочернего класса? Я хочу простенький менеджер памяти добавить, т.е. не освобождать память сразу, а откладывать указатель в кэш и при следующем создании сообщения такого же размера просто выдавать из кэша. Не помнимаю, зачем спрашивать на форуме то что можно прочесть в доке или самому проверить несколькими строками кода? Это настолько редкая в использовании фича, что вряд ли кто-то помнит подробности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 14:06 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyТак и надо делать. Это называется type erasure. Ок. Так и сделаю. Anatoly MoskovskyНе помнимаю, зачем спрашивать на форуме то что можно прочесть в доке или самому проверить несколькими строками кода? Это настолько редкая в использовании фича, что вряд ли кто-то помнит подробности. Мысли вслух. Вдруг кто помнит или какие-то подводные камни есть. Уже не важно, остаюсь на своем варианте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 16:06 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima T Код: plaintext 1. если уж хочется такого хардкора, то почему бы в msg не завести поле, которое будет хранить тип T? И потом в зависимости от него вызывать правильный деструктор (по сути, те же виртуальные функции) Во-вторых, а нужен ли деструктор для T? Или достаточно освободить память из-под объекта? В-третьих, присоединяюсь к идее про шаблонный класс. В-четвёртых, можно использовать те же "механизмы", которые используются в windows messaging А можно ещё такой финт сделать: при создании делать make_shared<T> а указатель хранить в поле msg, после удаления которой автоматически будет вызван деструтор T. Но тут надо подумать, потому как похоже на выстрел в ногу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 05:42 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
CEMbDima T Код: plaintext 1. если уж хочется такого хардкора, то почему бы в msg не завести поле, которое будет хранить тип T? И потом в зависимости от него вызывать правильный деструктор (по сути, те же виртуальные функции) Во-вторых, а нужен ли деструктор для T? Или достаточно освободить память из-под объекта? В-третьих, присоединяюсь к идее про шаблонный класс. В-четвёртых, можно использовать те же "механизмы", которые используются в windows messaging А можно ещё такой финт сделать: при создании делать make_shared<T> а указатель хранить в поле msg, после удаления которой автоматически будет вызван деструтор T. Но тут надо подумать, потому как похоже на выстрел в ногу. В реальном коде такого хардкора нет, есть msg_t переменной длины, упрощенно тут 20308304 msg_t нельзя делать шаблонным классом, т.к. например msg_t<int> и msg_t<std::string> надо ставить в одну очередь Без деструкторов уже все работает и с освобождением памяти под сообщением проблемы порешаны. Деструкторы нужны чтобы освобождать память которую T дополнительно в куче выделит, в первую очередь это касается объектов STD. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 07:13 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima Tmsg_t нельзя делать шаблонным классом, т.к. например msg_t<int> и msg_t<std::string> надо ставить в одну очередьшаблон можно специализировать в зависимости от того, класс ли T: std::is_class<T>, а в одну очередь можно поставить или через наследование от интерфейса или примерно так: 20172805 и 20256178 , там как раз идея скорости и отсутствия виртуальных функций в классах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 10:45 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima Tпропущено... msg_t нельзя делать шаблонным классом, т.к. например msg_t<int> и msg_t<std::string> надо ставить в одну очередь Без деструкторов уже все работает и с освобождением памяти под сообщением проблемы порешаны. Деструкторы нужны чтобы освобождать память которую T дополнительно в куче выделит, в первую очередь это касается объектов STD. как то так Код: 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. Можно ещё попробовать вариадик и/или мув симантику. Может сэкономить на конструкторах. . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 10:48 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
YesSql, долго пытался понять что я выигрываю по сравнению со своим вариантом 20308304 Все что вижу - это строчка на создании сообщения Код: plaintext 1. 2. 3. и у меня Код: plaintext 1. 2. 3. 4. Твой вариант получше, но это все плюсы. Дальше все точно также: при получении будет msg_t* и приведение его к исходному типу. Дальше отправка того же msg_t*. В твоем варианте мне надо курить перемещения (которые я не знаю), чтобы избавиться от копирования. Потом изучать перегрузку new/delete. Это минимум неделя изучения С++, а то и больше, я дотошный. Жалко мне неделю на это тратить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 18:18 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima TYesSql, долго пытался понять что я выигрываю по сравнению со своим вариантом 20308304 Хочешь вызвать корректный деструктор неизвестного сообщения? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 19:33 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
YesSqlХочешь вызвать корректный деструктор неизвестного сообщения? Я его и вызову 20308304 , msg->free это указатель на функцию, которая вызовет деструктор именно для того типа, который передан в конструктор. Как выше написали это стандартный велосипед вызова деструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 19:39 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
YesSql Код: plaintext 1. ИМХО нельзя так делать ->~ Это пистолет в кармане со снятым предохранителейм , прострел ноги вопрос времени , он рано или поздно произойдет в самый неожиданный момент. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 19:55 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
д0kХYesSql Код: plaintext 1. ИМХО нельзя так делать ->~ Это пистолет в кармане со снятым предохранителейм , прострел ноги вопрос времени , он рано или поздно произойдет в самый неожиданный момент. Это C++ карл, сдесь каждый угол заминирован. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 21:19 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Dima TYesSqlХочешь вызвать корректный деструктор неизвестного сообщения? Я его и вызову 20308304 , msg->free это указатель на функцию, которая вызовет деструктор именно для того типа, который передан в конструктор. Как выше написали это стандартный велосипед вызова деструктора. то же самое только без костыля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.03.2017, 21:27 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
Люблю я и C, и кресты, но как-то вместе они выглядят жутковато :) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Я бы, наверно, сделал как-то так, но вы говорите, что элегантность теряется. Может быть, спорить не буду. Кишки библиотеки просто выглядят, хм... странно для человека, который пишет C++. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.03.2017, 09:40 |
|
||
|
Как вызвать деструктор не зная тип объекта?
|
|||
|---|---|---|---|
|
#18+
ermak.nnКишки библиотеки просто выглядят, хм... странно для человека, который пишет C++. Сначала я хотел ограничится только С с классами, т.е. было Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Красиво и по Сишному. Оно так и осталось. Все что касается типов вложений хотел чтобы осталось поверх этого. Но как-то не очень код выглядит с постоянными <my_msg_t> Пока нет времени этим заниматься, подумаю, может вообще выкину все шаблоны и оставлю только явное наследование. Тесты показали что на скорость это никак не влияет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.03.2017, 10:28 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39422909&tid=2018237]: |
0ms |
get settings: |
12ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
169ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
| others: | 294ms |
| total: | 571ms |

| 0 / 0 |
