Один и тот же адрес, несколько счетчиков shared_ptr, запрещено ли это стандартом С++?

Предположим, мне нужно сделать следующее (это всего лишь образный код для обсуждения стандарта C++, поэтому я не буду обсуждать, почему я разработал его таким образом, поэтому не беспокойте меня чем-то вроде: ваш дизайн неверен .)

T* ptr = new T;
shared_ptr<T> p(ptr);
shared_ptr<T> q(ptr, SomeDeleterThatDoesnotDeleteButDoSomeOtherStuff());

Предположим, что логика гарантирует, что p или некоторые его копии живут дольше, чем все копии q, так что проблем практически не будет. Мой вопрос в том, запрещено ли это стандартом С++, например. явно указано как UB по стандарту С++, чтобы разные счетчики shared_ptr использовали один и тот же адрес?

Спасибо.


person Kan Li    schedule 18.06.2012    source источник
comment
Что, если вы return q;?   -  person Peter Wood    schedule 18.06.2012
comment
@Peter Я думаю, что это идея - вызвать неудаляющий и сделать что-то полезное, зная, что некоторое подмножество ссылок теперь пусто.   -  person Potatoswatter    schedule 19.06.2012
comment
Дизайн не настолько ужасен для своей цели. Вы можете гарантировать надлежащее уничтожение, заменив пользовательский модуль удаления тем, который действительно удаляет, а также владеет собственным shared_ptr 1. фиктивным объектом, который выполняет действие в своем деструкторе, или 2. имея другой пользовательский модуль удаления, который выполняет действие. Но эти методы могут быть менее эффективными, если набор(ы) q объектов быстро меняется относительно набора соответствующих владельцев p.   -  person Potatoswatter    schedule 19.06.2012
comment
@Potatoswatter, ты понял. На самом деле это именно то, что я делал в своей реальной работе: пусть тот, кто не удаляет, владеет p.   -  person Kan Li    schedule 19.06.2012
comment
@icando Но ... когда p выходит за рамки, он удалит ptr, а возвращенный q укажет на недопустимый объект без возможности узнать. Это кажется очень плохой идеей. Чего вы пытаетесь достичь?   -  person Peter Wood    schedule 19.06.2012
comment
@PeterWood, пожалуйста, прочитайте мои вопросы. Я уже говорил, что логика гарантирует, что p или некоторые его копии живут дольше, чем все копии q. Я также сказал, что не приветствую критику самого дизайна. В предыдущих комментариях я уже сказал, что предоставление удалению q копии p может обеспечить эту гарантию, что является деталью реализации, о которой я подумал, что неинтересно говорить, поэтому не стал задавать вопрос. Поэтому ситуация, на которой вы настаиваете в своем комментарии, никогда не произойдет.   -  person Kan Li    schedule 20.06.2012


Ответы (2)


Я не могу найти ничего в стандарте (ну, в окончательном варианте), что конкретно это исключает. Самое близкое, что я могу найти, это заметка в 20.9.11.2.10 shared_ptr casts

5 [Примечание: кажущееся эквивалентным выражение shared_ptr(static_cast(r.get())) в конечном итоге приведет к неопределенному поведению, попытке дважды удалить один и тот же объект. -конец примечания]

который на самом деле, кажется, забывает о вашем случае с помощью специального удаления.

person BoBTFish    schedule 18.06.2012

Если первый объект shared_ptr уничтожен, вы получаете UB, потому что объекты, использующие второй, могут получить доступ к освобожденному объекту.

Поскольку вы убедились, что ваш первый объект shared_ptr живет дольше второго, вы не получаете UB.

person BЈовић    schedule 18.06.2012