5

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

- (MyClass *)load {

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

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

我在 C++ 中有些不安地处理这个问题,因为它的非 ref-counted 环境似乎没有任何像autoreleaseCocoa 框架中定义的那样干净的东西,或者任何类型的所有权政策。C++ 中这种模式的最佳实践是什么?

我知道 auto_ptr,但它的使用也有很多问题,而且它似乎有太多缺点而不能像普遍存在的那样autorelease(奇怪的复制语义、不支持数组、与 STL 容器不兼容等)。

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

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

4

3 回答 3

8

C++03 世界(即 C++11 之前)中的“最佳实践”是以下两种情况之一:

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

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

  2. 使用某种形式的智能指针。std::auto_ptr很奇怪,但这与 C++03 中的轻量级差不多。不,您不能将它们放在标准容器中,但它确实定义了一种特定的所有权模式。Aboost::shared_ptr是一种更有效的方法,并且在许多其他地方更有用。

C++11 提供了std::unique_ptr,本质上是一个“固定的” auto_ptr。它依赖于 C++11 语言特性(对象移动),所以你不能只用 C++03 编写一个。您可以将它们存储在标准容器和所有东西中。但你不能只是传递它们。顾名思义,它们是独一无二的:它们中只有一个指向该对象。当它unique_ptr被销毁时,它会删除它引用的对象。

您只能通过放弃来转让a 的所有权。unique_ptr也就是说,您不能共享所有权。您可以返回所有权,这意味着调用者现在拥有它。您可以将所有权传递给另一个函数,这意味着该函数拥有它。但是没有两个实体可以通过 a 拥有一个对象unique_ptr

unique_ptr将是处理此类函数的首选方法。如果用户想自己非唯一地存储它,那么他们可以将它释放到 astd::shared_ptr中(这也被 C++11 采用)。

于 2011-11-23T00:56:42.537 回答
3

我会看看shared_ptrin boost。

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

于 2011-11-23T00:46:07.260 回答
2

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

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

于 2011-11-23T00:47:46.383 回答