[英]Why does the creation of a reference when assigning REQUIRE garbage collection?
我們的 C++ 講師發表了以下聲明:
每當某個變量的作用域結束時,編譯器會檢查該變量是對象本身還是對它的引用,從而決定是銷毀它並使所有對它的引用無效(在第一種情況下)還是保持原樣(在第二種情況下)。 因此,C++ 不可能選擇類似於 Python 或 Java 的策略,即將
a = b
視為a
到b
的新引用,因為在這種情況下,每次變量離開其作用域時,編譯器都必須檢查是否存在對同一對象的任何其他引用。 跟蹤這些信息基本上是垃圾收集,這不是 C++ 風格的。
我無法理解一件事:每當我們在 C++ 中銷毀一個對象時,我們仍然冒着整個程序中出現懸空引用的風險,不是嗎? 跟蹤它們完全是程序員的工作。
既然我們無論如何都必須跟蹤懸空引用,為什么在分配IMPLY垃圾收集時創建引用(從而使其可以在 C++ 中實現)? 還是我上面的說法錯了?
“因為無論如何我們都必須跟蹤懸空引用”......
好吧,事實證明我們通常不會為此煩惱。 作為一個簡單的例子,考慮復制構造函數Foo::Foo(Foo const& source)
。 該引用source
存在於復制構造函數中,但源對象存在於構造函數之外。 我們可以合理地假設調用者在復制對象時不會銷毀它——這將需要在另一個 CPU 內核上執行第二個線程,或者類似的不尋常的事情。 相反,我們依賴於一個共同的潛規則:如果你復制了一些東西,你就會讓源對象保持活動狀態,直到復制完成。
事實證明,在許多情況下,C++ 引用是短暫的,您不需要做任何特殊的事情。 更是如此,因為 C++ 引用不能被重新綁定——你以后不能引用另一個對象。 對於后者,C++ 有指針。
除了這些核心概念,C++還有智能指針。 這些有效地處理了單個對象的垃圾收集。
默認情況下,C++ 具有復制語義,並在顯式請求時具有引用語義。 當請求引用語義時,程序員應該跟蹤並避免使用懸空引用。 通常只對所有變量的一小部分請求引用語義,並且引用通常是短暫的,因此它們很少懸垂。
默認情況下具有引用語義的語言(例如 Python 或 Java)實際上需要 GC,因為在沒有 GC 的情況下,手動跟蹤每個變量和對象的生命周期對程序員來說是一種不合理的負擔。 理論上默認情況下可以使用引用語義並且沒有 GC,但是當人們開始處理比最小的玩具程序更多時,它變得相當不切實際。
默認情況下,引用語義也會破壞 RAII,而破壞 RAII 意味着破壞我們所知道的 C++。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.