#c #shared-ptr #double-dispatch #weak-ptr
#c #общий-ptr #двойная отправка #слабый ptr
Вопрос:
У меня есть некоторая логика, в которой я использую std:: shared_ptrs для объектов в иерархии наследования. В какой-то момент мне нужно обработать эти объекты в зависимости от их реального типа, поэтому я использую двойную отправку (т. Е. я вызываю метод в базовом классе, который затем, в свою очередь, вызывает метод для другого объекта с реальным типом, см., например, шаблон посетителя в GoF).
Теперь на этом этапе я мог бы либо передать ссылку на объект с правильным типом, либо копию. По нескольким причинам о копировании не может быть и речи. Ссылка обычно была бы в порядке, потому что вызов происходит в области ниже той, где находится shared_ptr, поэтому она не будет уничтожена во время выполнения этого вызова. Однако для некоторых подтипов мне нужно сохранить объект в контейнере STL, поэтому мне нужно быть абсолютно уверенным, что он не будет уничтожен. Очевидно, что голые указатели или новые shared_ptrs здесь не будут работать, поэтому мне нужно получить ссылку на shared_ptr, из которого это было вызвано.
Прямо сейчас я делаю следующее: я использую именованный конструктор вместо реального для создания объекта. Это устанавливает weak_ptr внутри объекта и выдает shared_ptr для использования объекта. Когда происходит двойной обратный вызов, я получаю новый shared_ptr из weak_ptr и сохраняю его в контейнере, чтобы объект не был уничтожен. Однако это делает мою логику построения действительно уродливой.
Есть ли лучший способ сделать это?
Ответ №1:
Производите свой класс от std::enable_shared_from_this
— тогда вы можете извлечь shared_ptr из своего объекта в любое время!
Это не сильно отличается от того, что вы делаете сейчас с weak_ptr
, но это чистая и общепринятая идиома для этого.
Ответ №2:
Вы можете передать shared_ptr своему объекту с правильным типом, используя dynamic_pointer_cast.