shared_ptr 和 unique_ptr 的不完整类型

incomplete types with shared_ptr and unique_ptr

我想了解为什么 unique_ptr 析构函数要求类型在销毁时是完整的,而 shared_ptr 不是这种情况。 This blog from Howard Hinnant 简要提到它与静态删除器和动态删除器有关。我正在寻找更详细的解释为什么会这样(它可能是特定于编译器实现的,在这种情况下,一个例子会有所帮助)。使用动态删除器,是否会限制析构函数被内联?

Howard Hinnant 正在简化。他的确切意思是,如果你使用 std::unique_ptr 的默认删除器,你需要一个完整的类型。对于默认删除器,它只是为您调用 delete

静态和动态删除器的要点是

class A;

void static_delete(A* p)
{
    delete p;
}

void (*dynamic_delete)(A*) = /* somehow */;

int main()
{
    A* p = /* somehow */;
    static_delete(p);  // undefined behaviour
    dynamic_delete(p); // maybe not
}

只要dynamic_delete指向一个定义了A的函数,你就有well-defined行为。

为了防止未定义的行为,默认的删除器会检查一个完整的类型,它可以实现为

void default_delete(A* p)
{
    static_assert(sizeof(A) > 0);
    delete p;
}

I would like to understand why unique_ptr destructors require the type to be complete upon destruction while that isn't the case with shared_ptr

我相信这就像默认析构函数需要知道数据成员的大小一样简单。对于unique_ptr,删除器是对象表示的一部分,而对于shared_ptr,实际的删除器并不那么相关,因为它存储在控制块中,无论您使用哪种删除器