【问题标题】:Objective C "autorelease" in C++ -- standard way to control object lifetime?C++中的Objective C“自动释放”——控制对象生命周期的标准方法?
【发布时间】:2012-01-04 09:02:12
【问题描述】:

我正在将一些代码从 Objective C 移植到 C++。我对 C++ 设计模式不像对 Objective C 那样熟悉。在 Cocoa 世界中,有一种非常常见的模式是编写返回“自动释放”对象的工厂方法。一些简单的事情:

- (MyClass *)load {

    MyClass* obj = [[MyClass alloc] init];
    return [obj autorelease];
}

这简单易懂。该方法拥有它分配的内存,但可以将其交还给调用者,同时放弃所有权。它不必知道或关心调用者对该内存做了什么。如果它保留它,该对象将继续存在。如果完全忽略,内存将在当前调用堆栈展开后的某个时间被释放。

我在 C++ 中有些不安地处理这个问题,因为它的非引用计数环境似乎没有任何像 autorelease 那样干净的东西,或者任何与可可框架。 C++ 中这种模式的最佳实践是什么?

我知道 auto_ptr,但它的使用也有很多顾虑,而且它似乎有太多缺点,无法像 autorelease 那样无处不在(奇怪的复制语义,不支持数组,与 STL 不兼容容器等)。

Boost 智能指针也是一个明显的候选对象,有些甚至实现了自己的引用计数。不过,对于这么普通的东西,我不得不依靠 3rd 方库,这对我来说似乎有点奇怪。

另一个带有 C 味道的选项是释放返回的内存,而是通过常用的命名约定表明调用者现在拥有返回的对象。这似乎有点陈旧,如果调用者不小心忽略了返回值,很容易出现不可见的泄漏。

【问题讨论】:

  • “不过,对于这么普通的东西,我不得不依靠第三方图书馆,这似乎有点奇怪。”习惯它。这就是 C++ 中的工作方式:您可以找到满足您需要的库,然后使用它们。内存的所有权在 C++ 中不是语法;它总是手动。

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


【解决方案1】:

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 采用)。

【讨论】:

    【解决方案2】:

    嗯,最类似于 c++ 的选项是使用智能指针..

    根据我的阅读,引用计数指针是你最好的选择,在 c++11 标准中你可以使用shared_ptr

    【讨论】:

      【解决方案3】:

      我会在 boost 中查看 shared_ptr

      C++ 世界是关于库的。因为没有人拥有 C++(与 Objective-C 不同),它会随着社区的需求而增长。

      【讨论】:

        猜你喜欢
        • 2011-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多