std :: shared_ptr и двойной обратный вызов - PullRequest
1 голос
/ 15 апреля 2011

У меня есть логика, когда я использую std :: shared_ptrs для объектов в иерархии наследования.В какой-то момент мне нужно обработать эти объекты в зависимости от их реального типа, поэтому я использую двойную диспетчеризацию (т.е. я вызываю метод в базовом классе, который затем, в свою очередь, вызывает метод для другого объекта с реальным типом, см., Например,шаблон посетителей в GoF).

Теперь я могу передать ссылку на объект с правильным типом или копию.По нескольким причинам копия не подлежит обсуждению.Ссылка, как правило, будет в порядке, потому что вызов происходит в области ниже той, где живет shared_ptr, поэтому он не будет уничтожен во время этого вызова.Однако для некоторых подтипов мне нужно хранить объект в контейнере STL, поэтому я должен быть абсолютно уверен, что он не будет уничтожен.Очевидно, что пустые указатели или новые shared_ptrs здесь не будут работать, поэтому мне нужно получить ссылку на shared_ptr, из которого это было вызвано.

Сейчас я делаю следующее: я использую именованный конструктор вместо реальногосоздать объект.Это устанавливает weak_ptr внутри объекта и выдает shared_ptr для использования объекта.Когда происходит двойной обратный вызов, я получаю новый shared_ptr из weak_ptr и сохраняю его в контейнере, поэтому объект не будет уничтожен.Однако это делает мою логику построения действительно ужасной.

Есть ли лучший способ сделать это?

Ответы [ 2 ]

8 голосов
/ 15 апреля 2011

Получите ваш класс из std::enable_shared_from_this - тогда вы можете извлечь shared_ptr из вашего объекта в любое время!

Это не сильно отличается от того, что вы делаете сейчас с weak_ptr, ноэто чистая и принятая идиома, чтобы сделать это.

1 голос
/ 15 апреля 2011

Вы можете передать shared_ptr вашему объекту с правильным типом, используя dynamic_pointer_cast .

...