我有一些项目广泛使用boost::shared_ptr
或std::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
- 所以我可以非常自由地替换基础类型;我怀疑这可以减轻潜在的切片/隐藏问题。
答案 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
,这应该可以正常工作。