简体   繁体   English

目标C“自动释放”在C ++中 - 控制对象生命周期的标准方法?

[英]Objective C “autorelease” in C++ — standard way to control object lifetime?

I'm in the process of porting some code from Objective C to C++. 我正在将一些代码从Objective C移植到C ++。 I'm not as familiar with C++ design patterns as I am with Objective C. In the Cocoa world, there is the very common pattern of writing a factory method that returns an "autoreleased" object. 我不熟悉C ++设计模式,就像我在Objective C中一样。在Cocoa世界中,有一种非常常见的编写工厂方法的模式,它返回一个“自动释放”的对象。 Somethings as simple as: 有些事情很简单:

- (MyClass *)load {

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

This is simple and easy to understand. 这很简单易懂。 The method owns the memory it allocates, but can hand it back to the caller, while simultaneously relinquishing ownership. 该方法拥有它分配的内存,但可以将其交还给调用者,同时放弃所有权。 It doesn't have to know or care what the caller does with that memory. 它不必知道或关心调用者对该内存的作用。 If it retains it, the object will survive. 如果它保留它,该对象将存活。 If it is completely ignored, the memory will be freed sometime after the current call stack is unwound. 如果完全忽略,则在解除当前调用堆栈后的某个时间释放内存。

I'm approaching this with some trepidation in C++, because its non ref-counted environment doesn't seem to have anything quite as clean as autorelease , or any kind of ownership policy that is as well defined as those in the Cocoa frameworks. 我在C ++中有些惶恐不安,因为它的非重新计数环境似乎没有像autorelease那样干净,或者任何类型的所有权策略都与Cocoa框架中的定义一样。 What are the best practices for this kind of pattern in C++? C ++中这种模式的最佳实践是什么?

I'm aware of auto_ptr, but there are also multitudes of concerns with its use, and it seems to have too many shortcomings to be as ubiquitous as autorelease (weird copy semantics, no support for arrays, incompatibility with STL containers, etc). 我知道auto_ptr,但是它的使用也存在很多问题,并且它似乎有太多缺点,无法像autorelease一样普遍存在(奇怪的复制语义,不支持数组,与STL容器不兼容等)。

Boost smart pointers are also an obvious candidate, and some even implement their own reference counting. 提升智能指针也是一个明显的候选者,有些甚至实现自己的引用计数。 It seems a little strange to me to have to lean on a 3rd party library for something this mundane though. 我不得不依靠第三方图书馆来寻找这个世俗的东西,这似乎有点奇怪。

Another option that reeks of C would be to just not release the returned memory, but indicate via come commonly adopted naming convention that the caller now owns the returned object. B的另一个选择是释放返回的内存,但是通过通常采用的命名约定来指示调用者现在拥有返回的对象。 This seems a bit archaic, and is prone to invisible leaks should the caller accidentally ignore the return value. 这似乎有点陈旧,如果调用者意外忽略返回值,则容易发生隐形泄漏。

The "best practices" in the C++03 world (that is, pre-C++11) are one of two things: C ++ 03世界中的“最佳实践”(即前C ++ 11)是以下两种方式之一:

  1. Do nothing. 没做什么。 This is essentially memory ownership by assumption/convention. 这基本上是假设/惯例的内存所有权。 If a function returns a pointer, you should know who owns it. 如果函数返回指针,您应该知道谁拥有它。 Usually, the documentation will tell you. 通常,文档会告诉你。 There is no specific syntax for ownership of memory or of transferring ownership. 内存所有权或转让所有权没有特定的语法。

    This is how an unfortunately large amount of C++ code out there manages memory. 这就是不幸的是,大量的C ++代码管理内存。 It can work, so long as everyone knows what they should be doing and who is responsible for what. 它可以工作,只要每个人都知道他们应该做什么以及谁负责什么。

  2. Use some form of smart pointer. 使用某种形式的智能指针。 std::auto_ptr is odd, but that's about as lightweight as it gets in C++03. std::auto_ptr是奇数,但它与C ++ 03中的轻量级相同。 No, you can't stick them in standard containers, but it does define a specific pattern of ownership. 不,您不能将它们粘贴在标准容器中,但它确实定义了特定的所有权模式。 A boost::shared_ptr is a more effective one, and is more useful in many other places. boost::shared_ptr是一个更有效的,在许多其他地方更有用。

C++11 offers std::unique_ptr , which is essentially a "fixed" auto_ptr . C ++ 11提供了std::unique_ptr ,它本质上是一个“固定”的auto_ptr It relies on C++11 language features (object movement), so you can't just write one in C++03. 它依赖于C ++ 11语言特性(对象移动),所以你不能只用C ++ 03编写一个。 You can store them in standard containers and everything. 您可以将它们存储在标准容器和所有东西中。 But you can't just pass them around. 但你不能只是传递它们。 As the name suggests, they're unique : only one of them can exist which points to that object. 顾名思义,它们是独一无二的 :只有其中一个可以存在,指向该对象。 When that unique_ptr is destroyed, it deletes the object it references. 当该unique_ptr被销毁时,它会删除它引用的对象。

You can transfer ownership of a unique_ptr only by giving it away. 您只能通过赠送来转移 unique_ptr所有权。 That is, you cannot share ownership. 也就是说,您无法共享所有权。 You can return ownership, which means that the caller now owns it. 您可以返回所有权,这意味着调用者现在拥有它。 You can pass ownership to another function, which means that that function owns it. 您可以将所有权传递给另一个函数,这意味着该函数拥有它。 But no two entities can own an object through a unique_ptr . 但是没有两个实体可以通过unique_ptr拥有一个对象。

unique_ptr would be the preferred method of handling a function like this. unique_ptr将是处理这样的函数的首选方法。 If the user wants to store it non-uniquely themselves, then they can release it into a std::shared_ptr (which was also adopted into C++11). 如果用户想要自己非唯一地存储它,那么他们可以将它释放到std::shared_ptr (它也被采用到C ++ 11中)。

I would look at the shared_ptr in boost. 我会看一下boost中的shared_ptr

The C++ world is all about libraries. C ++世界都是关于图书馆的。 Because no one owns C++ (unlike Objective-C), it grows as the community sees the need. 因为没有人拥有 C ++(与Objective-C不同),所以它随着社区的需要而增长。

Well the most c++-like option is using smart pointers.. 那么最像c ++的选项就是使用智能指针..

From what I read, reference counting pointers are your best bet, in the c++11 standard you can use the shared_ptr 从我读到的,引用计数指针是你最好的选择,在c ++ 11标准中你可以使用shared_ptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM