C++ 明确库拥有指针

C++ Make explicit that library owns pointers

本文关键字:拥有 指针 C++      更新时间:2023-10-16

是否通过使用智能指针。 我想向库的用户明确表示,他们传递到库中的所有指针现在都应该归库所有(即不由用户发布)。

许多开源库只是在他们的文档中声明库拥有或不拥有一切。 他们讨论了传入指针的预期生命周期。 当然,有一种更严格的方法来向用户传达此信息。

一个例子会很棒。

谢谢!

在所有类中使用拥有智能指针,该指针将获得所有权(即一旦完成任务,将销毁对象),并且从用户传递的任何指针都将被此拥有智能指针接管。

一个很好的例子是std::unique_ptr,一旦事情完成,就会破坏它的对象。

如果需要自定义销毁,可以向其传递自定义删除器。

当然,更好的是在您的类中同时进行创建(即通过make_unique),因为您将拥有RAII,这将避免所有泄漏。

如果你真的想要这样做,那么你应该在库中提供方法来创建这些对象,而不是让用户分配它们。库释放它未创建的对象是没有意义的,因为它不能保证它们都使用相同的分配工具。

有一个选项,库创建这些对象,包装在自定义智能指针中,该指针隐藏指针并且不允许外部客户端释放包装的对象,但始终可以绕过守卫。根据我的经验,试图变得太聪明总是适得其反:事情变得更加复杂,但使用库的开发人员总是可以胜过它。

IMO,最安全的方法是简单的生命周期管理API(例如CreateObject,DestroyObject)和清晰简洁的文档。然后用户可以自由选择如何处理生命周期(例如 shared_ptr/unique_ptr DestroyObject作为自定义删除器,或完全不同的东西)。

如果您编写库函数、方法和构造函数以按值获取std::unique_ptr<T>,则用户将无法自己释放指针,因为他们的unique_ptr实例将在参数的移动副本中清除。

class C;
void library_function(std::unique_ptr<C> by_value);
void user_code() {
    std::unique_ptr<C> user_c{std::make_unique<C>("param", 5)};
    library_function(user_c);
    assert(user_c.get() == nullptr);
}

如果用户应该能够继续观察对象,则可以在接口上接受shared_ptr,也可以提供返回原始(非拥有)指针或(更好的)引用的观察器方法。

一种方法是重载 new/delete 运算符,并使用这些函数来过滤访问。 例如,new 可能会创建对象,然后将地址存储到某个私有静态数据结构中。 删除可以设计为阻止任何使用delete object习惯用法的尝试,除非满足某些条件。