是否有C ++ 11的垃圾收集ABI的实际用途?

时间:2013-08-01 22:03:51

标签: c++ c++11 garbage-collection

C ++ 11引入了interface to garbage collectors。从我看来,它提供了一种与GC通信的标准化方式(例如declare_no_pointers),并获得有关如何处理伪装指针的信息(例如get_pointer_safety)。

然而,在C ++ 11中还没有标准化的方法来分配原始内存块,您无需手动释放。即使没有调用析构函数,也有一些用例会有所帮助。一个例子是实现高效的并发数据结构(如Herb Sutter所提到的),而不必处理复杂的清理协议。

到目前为止,这么好。我的问题(从一个普通的开发者,而不是GC库开发人员的角度来看):

是否有新的C ++ 11 GC界面为您提供帮助的实际示例?

至少从我的角度来看,世界并没有改变。如果您需要GC,您仍然需要找到非标准库,例如Boehm GC,并了解如何集成和使用它。新的标准化界面在这方面无济于事。它也不会解决可移植性问题。

(从长远来看,C ++ 11标准定义的通用接口有望得到回报。但是,我的问题仅针对不久的将来。)

2 个答案:

答案 0 :(得分:10)

不,目前没有当前 C ++ 11 GC接口的实际用法,因为在此期间没有完全支持此API的编译器。此外,C ++ 11标准将此API声明为可选,并且在主要编译器中没有看到实现它的动作(但是正如Jesse Good指出MSVC已经支持它)。

另外你应该看看这篇文章,它有相关的信息:Why garbage collection when RAII is available?

答案 1 :(得分:2)

std::shared_ptr提供所谓的引用计数垃圾收集。它实现起来很简单但有一些缺点。具体来说,它在许多应用程序中的效率低于其他形式的垃圾收集,更重要的是它无法处理循环引用。

Java和C#被称为“托管语言”而不是C ++,它被称为“非托管语言”,主要是因为它们实现了标记和清除垃圾收集。标记和清除垃圾收集处理循环引用。它通过逻辑搜索可到达对象的图形,然后定期删除那些无法访问的对象来完成此操作。有更复杂的算法是对此的优化(一个称为“世代”),但底层结构只是标记和扫描。

在C ++中实现标记和扫描的问题在于,有很多操作会使跟踪对象图变得困难。 “安全派生指针”概念旨在分离和定义这些问题,以便我们可以说明您可以使用哪些功能来维护对象图的GC视图的完整性。然后,编译器应该可以静态地识别和诊断违反这些构造的构造(重新解释转换,指针算术等)。

那些声称“为什么在你有RAII时你想要垃圾收集”的人会感到困惑。 RAII是一种使用所有权概念的可能内存模型。每个对象必须由其他一个对象拥有,并且该所有者负责其生命周期。对于许多对象模型而言,这不是自然的或方便的,因为一个对象被其他几个对象引用,并且没有明确的所有者。对于许多应用程序,您希望对象生存期在被取消引用后自动结束,这就是Java和C#“默认”工作的方式。

我的印象是新的内存模型和“安全派生对象”概念应该导致在标准库中提供真正的可选标记和清除垃圾收集器。这样的功能将非常受欢迎 - 但我认为它还没有。 “安全派生的对象”是未来事物的基础。