c++ - C++ 中的 Objective C "autorelease"——控制对象生命周期的标准方法?

标签 c++ objective-c memory-management ownership

我正在将一些代码从 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 之前的版本)中的“最佳实践”是以下两种情况之一:

  1. 什么都不做。这本质上是假设/约定的内存所有权。如果一个函数返回一个指针,你应该知道谁拥有它。通常,文档会告诉您。对于内存所有权或转移所有权没有特定的语法。

    不幸的是,这就是大量 C++ 代码管理内存的方式。它可以奏效,只要每个人都知道他们应该做什么以及谁负责什么。

  2. 使用某种形式的智能指针。 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/

相关文章:

ios - 传递给 prepareForSegue 的数据为零

c++ - 制作板的拷贝

c - 在 C 中的循环中分配和释放内存

C++ 分配段错误

c++ - C++中的内存管理模式

c++ - 为什么我们在内存中限制堆栈的大小而不是堆的大小

objective-c - dealloc 方法从 Xcode 4 中的 ViewController 实现文件模板中消失了吗?

objective-c - iOS - 在没有应用程序更新的情况下更新用户流程

c++ - 删除空指针是否安全?

c# - 无法解密这些字符串