![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
alexy |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
shared_ptr нельзя создать в конструкторе...
у меня сейчас в многопоточном коде часто появляются двухэтапные конструкторы. снчала создаешь shared_ptr потом вызываешь какой-нибудь registr или еще что-нибудь, куча отложенных созданий объектов, когда я бы мог создать его в конструкторе ,но создаю в фукнции ,которой он нужен, из-за этого появляются дополнительные проверки "не создал ли я его уже?", которых можно было бы избежать, если бы... к тому же мне не нравится shared_from_this с точки зрения ООП, это как бы деталь реализации, закравшаяся в интерфейс. может спасти intrusive_ptr, но у него нет weak_ptr и значит проблема циклических ссылок будет. вобщем сегодня я накатал такой код. не уверен в правильности использвания std::atomic. выбрал shared_ptr для быстроты реализации. потом хочу сделать структуру, одно поле будет счетчиком ссылок для объекта, другое для weak_ptr'а. выкладываю: может кому интересно или у кого-то уже есть свои проверенные наработки, лучше чем у меня, поделитесь пожалуйста. зы: а что, нельзя загружать файлы hpp ??
Прикрепленные файлы
|
|
|
lanz |
![]()
Сообщение
#2
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата shared_ptr нельзя создать в конструкторе... А зачем? Чтобы иметь член класса-указатель на себя самого? Или чтобы вызывать глобальные статические функции? В любом случае, лучше использовать factory[method].
|
|
|
alexy |
![]()
Сообщение
#3
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Или чтобы вызывать глобальные статические функции? ага, для нескольких типов у меня есть реестр. также вревовидные структуры.. некоторым нужно обязательно создать определенных детей. то есть например класс дерево обязательно должен содержать один лист и один орех, другое по желанию ![]() В любом случае, лучше использовать factory[method]. а чем лучше? нужно создавать паралельную эрархию классов. а если я хочу указатель на созданный тип, а не на базовый? с фабрикой останется только dynamic_cast. |
|
|
lanz |
![]()
Сообщение
#4
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата а чем лучше? Separation of concerns, разделяете тип хранения (shared_ptr), реестры и ваш класс. Тип хранения это деталь реализации. Вот например сейчас у вас один реестр, а захотите например 2, из которых один записывает в БД. Добавляете новую фабрику, с 2 реестрами и все. Хотите создаете с одним реестром, хотите с двумя. А если у вас занесение в реестр в конструкторе как вы это реализуете? параметр передавать в конструктор? if-then-else? Цитата а если я хочу указатель на созданный тип, а не на базовый? Interface segregation principle, значит у базового типа плохой интерфейс, возможно стоит сделать еще один? ![]() Если не хочется много писать, сделайте factory template:
|
|
|
alexy |
![]()
Сообщение
#5
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Separation of concerns, разделяете тип хранения ... Interface segregation principle, значит у базового типа плохой интерфейс, возможно стоит сделать еще один? ![]() это интересно.. может и стоит использовать фабрику.. еще проблема с параметрами для инициализации. на одном форуме нашел, что это не возможно. там чел потом сделал политику фкнциионирования, которую и передавал в качестве единственного параметра в фабрику. реестр - это не просто тип хранения, это обеспечение некторых функций, требуемых от объекта. это вобще сервер в нете. там есть класс сессии, это сеанс взаимодействия с пользователем. он регистрируется в реестре, например, если у пользователя пропадет интеренет, то есть специальный поток, который убивает сессии, которые слишком долго висят. также юзверь может подключится к этой сесии с другого клиента ну и т.д. есть сессия для всех, есть с обязательным залогиниванием. ей нужно в конструкторе передать параметры токена юзера. иначе, если этого не сделать, то выходит, что сессия будет какое-то время с незалогиненым пользователем. ЗЫ: да, мои гуглинья наводят меня на мысль, что это действительно никому не нужно и люди юзают другие способы. выходит что обычно такое рашется именно фабрикой? |
|
|
lanz |
![]()
Сообщение
#6
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата еще проблема с параметрами для инициализации. на одном форуме нашел, что это не возможно. там чел потом сделал политику фкнциионирования, которую и передавал в качестве единственного параметра в фабрику. Почему же невозможно, можно в метод create передавать все нужные параметры. Цитата ЗЫ: да, мои гуглинья наводят меня на мысль, что это действительно никому не нужно и люди юзают другие способы. выходит что обычно такое рашется именно фабрикой? Просто делать это в конструкторе - плодить лишние зависимости. Тут надо подумать, кто является владельцем сессии и на него возложить заботу о создании, хранении и т.п. Самой сессии знать о центральном реестре и других сессиях на мой взгляд излишне. Сообщение отредактировал lanz - 15.4.2015, 16:11 |
|
|
Iron Bug |
![]()
Сообщение
#7
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
может, я не совсем понимаю идею, но чем не устраивает make_shared, например?
|
|
|
lanz |
![]()
Сообщение
#8
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата может, я не совсем понимаю идею, но чем не устраивает make_shared, например? После создания хочется выполнять еще какие-то обязательные действия, не только завернуть указатель. Цитата иначе, если этого не сделать, то выходит, что сессия будет какое-то время с незалогиненым пользователем. Это как раз не страшно. Введите состояния сессии и отслеживайте их. Просто если логинится в конструкторе, то как обрабатывать ошибки? |
|
|
Iron Bug |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
один фиг непонятно, чего хотели получить в итоге. а можно пример использования класса и что конкретно не получается?
можно создавать shared_ptr и использовать инициализацию в конструкторе, при этом можно в конструктор передавать shared_ptr'ы на другие объекты. можно через enable_shared_from_this создавать weak_ptr на себя и потом возвращать shared_ptr, полученный из this, через какой-то метод. |
|
|
alexy |
![]()
Сообщение
#10
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Просто если логинится в конструкторе, то как обрабатывать ошибки? ну, я ввел понятие токена. сессия без логина, не принимает никаких параметоров, сессия с логином, принимает строку токена, ну и не создается (throw login_error) если токен не верен. я вот гуглил. виджеты, на сколько я понимаю, так создать нельзя. потому что везде они создаются обычным new. и действительно, у меня есть виджет, который содержит другие виджеты, то есть у него прямо в конструкторе создаются неслько других виджетов, которые он должен удалить когда удалится сам. как им указать родителя в конструкторе? я просто делаю клиента html, сделал виджетами. один может содержать другой, но есть root - это как бы <html></html> и у него несколько виджетов - <head> <body> и пара других. изначально сделал widget_ptr, и метод parent возращает widget_ptr, но оказалось, что так не получится если я хочу создать в конструкторе виджеты, то есть если он составной. мне кажется как-то не правильно создавать в фабричном методе внутренние детали виджета. один фиг непонятно, чего хотели получить в итоге. а можно пример использования класса и что конкретно не получается? можно создавать shared_ptr и использовать инициализацию в конструкторе, при этом можно в конструктор передавать shared_ptr'ы на другие объекты. можно через enable_shared_from_this создавать weak_ptr на себя и потом возвращать shared_ptr, полученный из this, через какой-то метод. да, я об этом писал в первом посте. мне не нравится shared_from_this() то есть если он public, то выходит что это реализация в интерфейсе. я делаю его protected. но в конструкторе все равно не получается. то есть получится, если сделать какой-нибудь метод, get_shared, тогда выйдет
а сам get_shared, после первого использования должен сделать shared_to_this.release(); или что-нибудь в этом духе, чтобы остался только weak_to_this... по мне лучше что-нибудь в таком духе (в конструкторе)
Сообщение отредактировал alexy - 16.4.2015, 13:46 |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 3.5.2025, 19:48 |