У меня есть несколько проектов, которые используют 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
— так что я могу довольно свободно заменить базовый тип; и я подозреваю, что это уменьшает потенциальную проблему срезания / скрытия.
Там действительно нет «магии» в std::shared_ptr<T>
это будет удалено, если вы поместите его в пользовательский класс, который вызовет исключение при разыменовании NULL
общий указатель Так что я не понимаю, почему такой подход не сработает, если ваш новый класс-оболочка следует всей семантике std::shared_ptr<T>
тип.
Кстати, вы могли бы также принять немного другой подход, и это создать класс-обертку, который просто не позволит другим пройти NULL
указатели на завернутые std::shared_ptr<T>
Данные-члены на первом месте. В основном это будет класс, который будет обеспечивать соблюдение std::make_shared<T>
идиома в своем конструкторе. Я не уверен, основываясь на работе вашего кода, если это возможно, но это еще один способ обойти проблему, используя подход RAII, а не выбрасывая исключения.
Просто подкласс std::shared_ptr
в throwing_shared_ptr
переопределите эти два метода, сделайте так, чтобы они утверждали и вызывали std::shared_ptr
Импл. Это должно работать нормально, пока вы используете throwing_shared_ptr
везде вместо того, чтобы нарезать его на std::shared_ptr
,