自定义std :: shared_ptr或boost :: shared_ptr以在NULL取消引用时抛出异常

时间:2012-09-17 02:41:32

标签: c++ exception c++11 shared-ptr libc++

我有一些项目广泛使用boost::shared_ptrstd::shared_ptr(我可以很快转换为任何一个实现,如果对于一个问题有一个很好的答案,而不是另一个问题)。 Boost实现使用Boost.Assert来避免在运行时遇到operator*operator->中的空(NULL)指针时返回;而libc ++实现似乎没有任何检查。

当然,在使用之前应该检查shared_ptr的有效性,一个大的,混合范式的代码库让我想要尝试抛出异常的变异;因为大多数代码都是相对异常感知的,并且最多会失败到高级但可恢复的状态,而不是std::terminate()或段错误。

如何在保持shared_ptr的稳健性的同时,如何最好地自定义这些访问者?似乎将shared_ptr封装在throwing_shared_ptr中可能是最佳选择,但我对打破魔法持谨慎态度。我最好复制Boost源代码,只需将ASSERT更改为适当的throw语句吗?


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

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

所有东西都传递,接受或存储ClassPtr - 所以我可以非常自由地替换基础类型;我怀疑这可以减轻潜在的切片/隐藏问题。

2 个答案:

答案 0 :(得分:5)

std::shared_ptr<T>中真的没有“魔法”,如果你将它包装在一个自定义类中,它会在取消引用NULL共享指针时引发异常。所以我不明白为什么这种方法不起作用,只要你的新包装类遵循std::shared_ptr<T>类型的所有语义。

顺便说一下,您也可以采用稍微不同的方法,这就是创建一个包装类,它不会允许其他人将NULL指针传递给包含std::shared_ptr<T>数据成员第一名。基本上它将是一个在其构造函数中强制执行std::make_shared<T>成语的类。我不确定,如果可能的话,基于你的代码的工作方式,但这是使用RAII方法而不是抛出异常来规避问题的另一种方法。

答案 1 :(得分:5)

std::shared_ptr子类化为throwing_shared_ptr,覆盖这两种方法,让它们断言并调用std::shared_ptr的impl。只要您在任何地方使用throwing_shared_ptr而不是将其切片为std::shared_ptr,这应该可以正常工作。