3

虽然std::shared_ptr有很多工作,但我有点想念一个shared_ref实现。这是 的一种特殊化shared_ptr,它保证它永远不会包装 a nullptr(当然,在正确使用的情况下)。我有点想知道为什么它不在 C++11 标准中。实施过程中是否有市长问题?在我的头顶上,我想不出任何东西。

编辑:

我希望有一个类似于:

template <typename T>
class shared_ref {
public:
  shared_ref( T&& ref );
  T& get();
  T* operator&() const;

  template< class Y > 
  void reset( Y&& obj );

  long use_count() const;
  bool unique() const;

  void swap( shared_ref& r );
};
4

2 回答 2

3

实施过程中是否有市长问题?

这是一个:您不能拥有reference的所有权。智能指针的全部意义在于声明指针本身的所有权。shared_ref无法工作,因为您无法控制引用的生命周期。

不,这也不会飞:

shared_ref( T&& ref ) : p(&ref) {}

用户可能已经给了您一个堆栈变量,这意味着您现在在此对象和堆栈变量之间拥有“共享”所有权。堆栈变量不能与某些东西共享所有权。

您只能控制指针的生命周期。并且指针可以为NULL。因此,您唯一能做的就是运行时检查指针是否为 NULL。

您可以做的最好的事情是一个等效的接口,shared_ptr除了它没有默认构造函数并且在被赋予 NULL 的情况下抛出。这真的值得创建一个全新的指针类型吗?


C++ Core Guidelines 支持库具有not_null模板,可应用于大多数类似指针的类型。因此,您可以not_null<shared_ptr>在要验证指针是否为 NULL 时使用,但只能在它进入使用时使用一次。初始创建指针后,无需再次检查。

当然,您不能强迫其他人使用它们,但始终使用该类型将解决问题。

于 2012-07-06T17:24:48.023 回答
0

只有两种方法可以使 ashared_ptr为空 - 要么是默认构造的,要么在某个时候被分配了一个空值。由于您已经同意默认构造您的假设类是没有意义的shared_ref,因此只剩下第二个条件。

如果您尝试将 a 分配nullptr给您的shared_ref对象,您希望会发生什么?它应该抛出错误吗?shared_ptr使用简单的模板函数对常规做同样的事情是微不足道的:

template<typename T>
T* notnull(T* ptr)
{
    if (ptr == std::nullptr)
        throw std::invalid_argument(std::string("nullptr"));
    return ptr;
}

std::shared_ptr<int> pint = notnull(GetIntPtr());

通常,除非有迫切的需求且没有简单的解决方法,否则不会将内容添加到标准中。

于 2012-07-06T16:52:31.327 回答