当shared_ptr调用派生和基础析构函数时,为什么unique_ptr只调用基础析构函数?

时间:2018-03-12 04:26:50

标签: c++

为什么以下代码的输出会有所不同,具体取决于我使用shared_ptr还是unique_ptrshared_ptr的输出是有意义的,因为对象是完全被破坏的,而在unique_ptr的情况下,只有基类部分被破坏。我认为当我使用智能指针时,我不必使析构函数virtual成功破坏整个对象。

#include <iostream>
#include <memory>
using namespace std;
class base
{
  public:
  base(){cout <<"base class constructor " <<endl;}
  ~base(){ cout <<"base class Destructor "<<endl;}
};
class derv: public base
{
  public:
  derv(){cout <<"derv class constructor " <<endl;}
  ~derv(){ cout <<"derv class Destructor "<<endl;}
};

shared_ptr调用上述代码时,完整对象(basederv)将被销毁。

int main()
{
  shared_ptr<base> p1 (new derv);
}
Output:
 base class constructor                                                                              
 derv class constructor                                                                              
 derv class Destructor                                                                                    
 base class Destructor

unique_ptr调用时,只会导致base部分被破坏而derv部分被破坏。

int main()
{
  unique_ptr<base> p1 (new derv);
}
Output:
 base class constructor                                                                              
 derv class constructor
 base class destructor                                                                         

1 个答案:

答案 0 :(得分:3)

我认为你知道为什么会这样做的机制。如果您需要复习,请参阅Why unique-ptr doesn't check base class to virtual destructible?。这个问题的答案给出了详细的机制。

我认为你的问题是,为什么标准会这样做?答案很简单。使用shared_ptr,可以清楚地显示有关使用哪个删除器的信息,并且您将引用计数和可能是指向对象的实际指针放在同一位置。

后者是时间/空间的权衡。这取决于你的shared_ptr对象是否有指向引用计数的指针和指向对象的指针,或者只是指向一个&#39;句柄&#39;包含对象指针和所有其他所需信息。你想要什么,一个较小的指针,或一个指针,它不需要做一个额外的间接级别来获得指向对象的指针?

使用unique_ptr,无法放置此信息。你可以将它放在unique_ptr对象本身,但那个对象将是普通指针的2-3倍,并且这根本不是标准的目标。任何人都没有理由不使用unique_ptr,因此它必须以各种方式执行,至少与常规指针一样。