定制的std :: shared_ptr的或升压:: shared_ptr的扔在NULL取消引用异常

2019-09-22 11:54发布

我使用的几个项目boost::shared_ptrstd::shared_ptr广泛(我可以转换成任何一种实现很快就好了,如果有一个很好的回答这个问题的一个,而不是其他)。 升压实现使用Boost.Assert以避免在遇到在一个空(NULL)的指针的情况下,返回operator*operator->在运行时; 而的libc ++实现似乎缺乏任何检查。

虽然课程的有效性shared_ptr使用前应进行检查,大,混合模式的代码库使我想尝试一个异常抛出的变化; 因为大部分的代码是相对识别异常,并会在最失败的一个高的水平,但可恢复状态,而不是std::terminate()或段错误。

我应该如何最好的自定义这些访问,同时保持稳健shared_ptr ? 看来,封装shared_ptrthrowing_shared_ptr可能是最好的选择,但我警惕打破了魔术。 我是不是最好关闭复制升压源,只是改变了ASSERT s到适当的throw声明?


到处用于适当的实际类型名称smart_ptr<T>类型是从宏观扩展一个typedef; 即ForwardDeclarePtr(Class)扩展为类似:

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

一切通过,需要,或者存储有ClassPtr -这样我就可以自由地漂亮取代的基础类型; 我怀疑这减轻了潜在的切片/隐藏的问题。

Answer 1:

确实没有“神奇”中std::shared_ptr<T>如果你把它包解引用时会抛出异常的自定义类中,将被删除NULL共享指针。 所以,我不明白为什么这种做法是行不通的,只要你的新的包装类遵循的所有语义std::shared_ptr<T>类型。

顺便说一句,你还可以采取稍微不同的方法,那就是创建一个包装类,根本不会允许别人传递NULL指针包裹std::shared_ptr<T>数据成员的第一名。 基本上,它是将强制执行一类std::make_shared<T>在其构造成语。 我不知道,根据你的代码,如果这是可能的工作方式,但它的另一个方式使用RAII方法,而不是抛出异常来规避这个问题。



Answer 2:

刚子类std::shared_ptrthrowing_shared_ptr ,覆盖这两种方法,并让他们主张并呼吁通过到std::shared_ptr的IMPL。 你用这应该罚款,只要工作throwing_shared_ptr无处不在,而不是它切到的std::shared_ptr



文章来源: Customising std::shared_ptr or boost::shared_ptr to throw an exception on NULL dereference