我正在将一些代码从 Objective C 移植到 C++。我对 C++ 设计模式的熟悉不如对 Objective C 的熟悉。在 Cocoa 世界中,有一种非常常见的模式,即编写返回“自动释放”对象的工厂方法。一些简单的事情:
- (MyClass *)load {
MyClass* obj = [[MyClass alloc] init];
return [obj autorelease];
}
这个简单易懂。该方法拥有它分配的内存,但可以将其交还给调用者,同时放弃所有权。它不必知道或关心调用者对该内存做了什么。如果保留它,该对象将存活。如果完全忽略,内存将在当前调用堆栈展开后的某个时间释放。
我在 C++ 中有些惶恐地接近这个,因为它的非引用计数环境似乎没有像 autorelease
那样干净的东西,或者任何类型的所有权政策与 Cocoa 框架中定义的一样。 C++ 中这种模式的最佳实践是什么?
我知道 auto_ptr,但它的使用也有很多问题,而且它似乎有太多缺点,无法像 autorelease
一样普遍(奇怪的复制语义,不支持数组、与 STL 容器不兼容等)。
Boost 智能指针也是一个明显的候选者,有些甚至实现了自己的引用计数。不过,对于这种平凡的事情,我不得不依赖第三方库,这对我来说似乎有点奇怪。
C 的另一个选择是不释放返回的内存,但通过普遍采用的命名约定表明调用者现在拥有返回的对象。这看起来有点过时,如果调用者不小心忽略了返回值,则很容易出现不可见的泄漏。
最佳答案
C++03 世界(即 C++11 之前的版本)中的“最佳实践”是以下两种情况之一:
什么都不做。这本质上是假设/约定的内存所有权。如果一个函数返回一个指针,你应该知道谁拥有它。通常,文档会告诉您。对于内存所有权或转移所有权没有特定的语法。
不幸的是,这就是大量 C++ 代码管理内存的方式。它可以奏效,只要每个人都知道他们应该做什么以及谁负责什么。
使用某种形式的智能指针。
std::auto_ptr
很奇怪,但它与 C++03 中的一样轻量级。不,你不能把它们放在标准容器中,但它确实定义了一种特定的所有权模式。boost::shared_ptr
是一种更有效的方法,在许多其他地方也更有用。
C++11 提供了 std::unique_ptr
,它本质上是一个“固定的”auto_ptr
。它依赖于 C++11 语言特性(对象移动),所以你不能只用 C++03 编写一个。您可以将它们存储在标准容器和任何东西中。但你不能只是传递它们。顾名思义,它们唯一:只有其中一个指向该对象。当 unique_ptr
被销毁时,它会删除它引用的对象。
您只能通过赠送 unique_ptr
来转让所有权。也就是说,您不能共享所有权。您可以返回所有权,这意味着调用者现在拥有它。您可以将所有权传递给另一个函数,这意味着该函数拥有它。但是没有两个实体可以通过 unique_ptr
拥有一个对象。
unique_ptr
将是处理此类函数的首选方法。如果用户想自己非唯一地存储它,那么他们可以将它释放到 std::shared_ptr
(也被 C++11 采用)。
关于c++ - C++ 中的 Objective C "autorelease"——控制对象生命周期的标准方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8235946/