C++11垃圾回收器 - 为什么和如何使用

45
C++11的语言特性列表中,有以下内容:

最小支持垃圾回收和基于可达性的泄漏检测

(但似乎GCC和Clang都没有实现。)
为什么标准委员会引入了这个垃圾回收C++语言特性?
C++真的需要GC吗?RAII不是一种非常优秀的模式(可以统一用于内存和非内存资源,如套接字、文件、纹理等)吗?
GC会破坏使用RAII的C++代码模式的统一性吗?
有些人说,GC可以方便地打破循环依赖关系,但是使用像weak_ptr这样的智能指针不就可以了吗?
在抛出异常的情况下会发生什么?堆栈展开语义将如何修改以考虑GC?
是否也会引入类似于C#的IDisposable模式?
此外,假设在C++中引入了GC,指针语法会有所不同吗?例如,我们是否会有类似于C++/CLI或C++/CX扩展中的帽子状“指针”^?应该有一种方法来区分普通原始指针和“托管”指针,对吧?

8
C++ 没有垃圾回收机制,且将来也不会有。 - Alex Chamberlain
27
C++的垃圾回收机制(GCs)已经存在了很长时间。 - R. Martinho Fernandes
2
垃圾回收不属于语言的一部分。然而,新的语言特性试图使为C++创建垃圾回收库变得更加容易。 - Kerrek SB
2
@Mr.C64,这并不是规定。没有任何规范:任何实现都可以自由地做任何他们想做的事情。 - R. Martinho Fernandes
5
C++已经有垃圾回收机制,只是不是标准化的。实际上,在C++11中曾提出将其加入标准,但委员会时间不够,最终未被采纳。 - James Kanze
显示剩余8条评论
3个回答

62
该提案并未引入垃圾回收器 - 它只是在某些情况下允许(如果实现选择)使用。标准将仅将这些情况描述为导致未定义行为。通过这样做,它放宽了对实现的要求,为垃圾回收器提供最小的灵活性。 该提案中给出的简单示例考虑了当您获取指向动态分配对象的指针时,将其与另一个值进行XOR运算,从而隐藏指针值,然后恢复原始指针值以通过它访问对象的情况。在C++11之前,这是完全可以接受的,并且仍然可以使用。但是,现在这样的操作可能被视为未定义行为(请参见下一段),这意味着实现可能会对指向的对象进行垃圾回收。
标准规定,实现可以具有放松指针安全性,在这种情况下,行为与之前相同,或者严格指针安全性,这允许引入垃圾回收器。
一个实现可能具有宽松指针安全性,在这种情况下,指针值的有效性不取决于它是否是安全派生的指针值。或者,一个实现可能具有严格指针安全性,在这种情况下,除非引用的完整对象具有动态存储期并已被声明为可达(20.6.4),否则不是安全派生的指针值是无效的指针值。... ... 是否具有宽松或严格的指针安全性是由实现定义的。

如果一个指针值指向一个动态分配的对象,并且没有发生任何有趣的事情(在§3.7.4.3中更具体地定义),那么这个指针值就是一个安全派生的指针值。

如果您的实现具有严格的指针安全性,但仍希望对指针进行所述有趣的操作而不引入未定义的行为,则可以将指针p声明为可达,如下所示:

declare_reachable(p);

该函数在<memory>头文件中定义,与相关函数一起,如undeclare_reachabledeclare_no_pointersundeclare_no_pointers。您还可以使用get_pointer_safety确定实现的严格程度。

例如,托管对象没有指定特殊的语法吗?没有“^”或其他什么符号吗?标准对于抛出异常时垃圾回收的行为没有任何规定吗? - Mr.C64
@Mr.C64 没错。没有提到垃圾回收器。 - Joseph Mansfield

22

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接