Настройка std :: shared_ptr или boost :: shared_ptr для выдачи исключения при разыменовании NULL

У меня есть несколько проектов, которые используют boost::shared_ptr или же std::shared_ptr широко (я могу преобразовать в любую реализацию достаточно скоро, если есть хороший ответ на этот вопрос для одного, но не другого). Реализация Boost использует Boost.Assert, чтобы избежать возврата в случае обнаружения пустого (NULL) указателя в operator* или же operator-> во время выполнения; в то время как реализация libc ++, кажется, не имеет никакой проверки.

Хотя, конечно, срок действия shared_ptr перед использованием следует проверить, большая кодовая база смешанной парадигмы заставляет меня захотеть попробовать вариант, генерирующий исключение; так как большая часть кода относительно осведомлена об исключениях и в большинстве случаев не сможет перейти на высокоуровневое, но возобновляемое состояние, а не std::terminate() или сегфо.

Как лучше настроить эти средства доступа, сохраняя при этом надежность shared_ptr? Кажется, что инкапсуляция shared_ptr в throwing_shared_ptr Может быть, лучший вариант, но я опасаюсь сломать магию. Мне лучше всего скопировать источник Boost и просто изменить ASSERTс соответствующим throw заявление?


Фактическое имя типа используется везде для соответствующего smart_ptr<T> type — это typedef, развернутый из макроса; то есть ForwardDeclarePtr(Class) расширяется до чего-то вроде:

class Class;
typedef boost::smart_ptr<Class> ClassPtr;

Все проходит, берет или хранит ClassPtr — так что я могу довольно свободно заменить базовый тип; и я подозреваю, что это уменьшает потенциальную проблему срезания / скрытия.

5

Решение

Там действительно нет «магии» в std::shared_ptr<T> это будет удалено, если вы поместите его в пользовательский класс, который вызовет исключение при разыменовании NULL общий указатель Так что я не понимаю, почему такой подход не сработает, если ваш новый класс-оболочка следует всей семантике std::shared_ptr<T> тип.

Кстати, вы могли бы также принять немного другой подход, и это создать класс-обертку, который просто не позволит другим пройти NULL указатели на завернутые std::shared_ptr<T> Данные-члены на первом месте. В основном это будет класс, который будет обеспечивать соблюдение std::make_shared<T> идиома в своем конструкторе. Я не уверен, основываясь на работе вашего кода, если это возможно, но это еще один способ обойти проблему, используя подход RAII, а не выбрасывая исключения.

5

Другие решения

Просто подкласс std::shared_ptr в throwing_shared_ptrпереопределите эти два метода, сделайте так, чтобы они утверждали и вызывали std::shared_ptrИмпл. Это должно работать нормально, пока вы используете throwing_shared_ptr везде вместо того, чтобы нарезать его на std::shared_ptr,

5

По вопросам рекламы [email protected]