通过或不使用智能指针。我想向库的用户明确说明,他们传递到库中的所有指针现在都应该归库所有(即,不由用户发布)。
许多开源库只是在其文档中声明该库拥有或不拥有一切。他们讨论了传入指针的预期寿命。当然,有一种更严格的方法可以将此信息传达给用户。
一个例子会很棒。
谢谢!
通过或不使用智能指针。我想向库的用户明确说明,他们传递到库中的所有指针现在都应该归库所有(即,不由用户发布)。
许多开源库只是在其文档中声明该库拥有或不拥有一切。他们讨论了传入指针的预期寿命。当然,有一种更严格的方法可以将此信息传达给用户。
一个例子会很棒。
谢谢!
如果你真的想要,那么你应该在库中提供方法来创建这些对象,而不是让用户分配它们。库释放它没有创建的对象是没有意义的,因为它不能保证它们都使用相同的分配工具。
有一个选项是库创建这些对象,包装在自定义智能指针中,该指针隐藏指针并且不允许外部客户端释放包装的对象,但总是可以绕过守卫。根据我的经验,试图变得太聪明总是适得其反:事情变得更加复杂,但使用该库的开发人员总是可以胜过它。
IMO,最安全的方法是简单的生命周期管理 API(例如 CreateObject、DestroyObject)和清晰简洁的文档。然后用户可以自由选择如何处理生命周期(例如/shared_ptr
作为自定义删除器,或完全不同的东西)。unique_ptr
DestroyObject
在所有类中使用拥有的智能指针,这将获得所有权(即,一旦使用它就会销毁对象),并且从用户传递的任何指针都将被这个拥有的智能指针接管。
一个很好的例子是std::unique_ptr
,一旦事情完成,就会破坏它的对象。
如果您需要自定义销毁,您可以将其传递给自定义删除器。
当然更好的是make_unique
在你的类中同时创建(即通过),因为你将拥有 RAII,这将避免所有泄漏。
如果您编写库函数、方法和构造函数以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
习语的尝试,除非满足某些条件。