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