unique_ptr <> v shared_ptr <>关于销毁策略

R S*_*hko 17 c++ c++11

我一直在教自己作为C++ 0x一部分的智能指针,并且遇到了一些与我不一致的东西.具体来说,如何处理unique_ptr <>和shared_ptr <>的销毁策略.

对于unique_ptr <>,您可以专门化std :: default_delete <>,从那时起,除非您明确请求其他销毁策略,否则将使用新的默认值.

考虑以下:

struct some_c_type;

some_c_type *construct_some_c_type();
void destruct_some_c_type(some_c_type *);

namespace std  {
    template <> struct default_delete<some_c_type> {
        void operator()(some_c_type *ptr) {
            destruct_some_c_type(ptr);
        }
     };
}
Run Code Online (Sandbox Code Playgroud)

现在,一旦到位,unique_ptr <>将默认使用适当的销毁策略:

// Because of the specialization, this will use destruct_some_c_type
std::unique_ptr<some_c_type> var(construct_some_c_type());
Run Code Online (Sandbox Code Playgroud)

现在将其与shared_ptr <>进行比较.使用shared_ptr <>,您需要显式请求相应的销毁策略,或者默认使用operator delete:

// error, will use operator delete 
std::shared_ptr<some_c_type> var(construct_some_c_type());

// correct, must explicitly request the destruction policy
std::shared_ptr<some_c_type> var(construct_some_c_type(),
                                 std::default_delete<some_c_type>());
Run Code Online (Sandbox Code Playgroud)

两个问题.

  1. 我是否正确,shared_ptr <>要求每次使用时都指定销毁策略,或者我错过了什么?
  2. 如果我没有遗漏某些东西,任何想法为什么两者都不同?

PS我关心这个的原因是我的公司做了很多混合的C和C++编程.C++代码通常需要使用C风格的对象,因此指定不同的默认销毁策略的简便性对我来说非常重要.

Unc*_*ens 4

我认为问题归结为为什么 std::shared_ptr 可以没有关联的删除器(在这种情况下它只是调用delete)而不是std::default_delete默认构造一个。(不知道。如果目的是default_delete为了专业化,人们会期望它被使用shared_ptr。)

否则就需要权衡。

模板参数越少越好。Boost 的参考文献提到,这允许工厂更改分配方案,而更改不会影响工厂的用户。

unique_ptr另一方面,A应该是非常轻量级的。如果删除器不是类型的一部分(GCC 使用元组,其中无成员对象不占用内存空间),您将如何以零空间开销存储删除器(在没有成员的函子的情况下)?


主观上,我想我更喜欢:

unique_ptr<FILE, FCloser> f(fopen(x, y));
Run Code Online (Sandbox Code Playgroud)

unique_ptr<FILE> f(fopen(x, y)); //default_delete<FILE> has been specialized
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,没有什么可猜测的。如果资源不是来自newnew[],则必须显式给出删除器。