2012-07-12 56 views
2

爲了依賴注入(測試驅動開發)的目的,我正在使用大量接口。出於這個原因,很多我的對象都是通過std :: shared_ptr指向的。我會使用std :: unique_ptr,但他們沒有複製構造函數當谷歌嘲笑所需。使用std :: shared_ptr檢測循環引用

如果發生循環引用,可以採取哪些措施來儘早發現循環引用?

我正在與谷歌測試的Linux平臺上工作。

回答

1

如果您有同質對象圖(即Node -> Node -> Node ...),則可以使用常用的週期檢測算法。

如果你的圖形是異構的(Document -> Element -> Table -> Document或其他),遍歷它可能太痛苦了......雖然也許是巧妙的自定義迭代器類型。

在這種情況下,更常見的是構建您的所有權語義,因此可能沒有循環,可能使用weak_ptr打破靜態可識別的循環。

+0

在你的例子中,文檔 - >元素 - >表格 - >文檔,只有在表和文檔之間需要一個弱ptr,對吧?如果一個Element有一個next()方法來獲取指向下一個兄弟的指針會怎麼樣。那麼應該使用什麼樣的指針? – Baz 2012-07-12 11:23:48

+0

如果有一個共同的基礎和一個虛擬的'next'方法,我會把它算作基本類型FWIW的同質圖。但總的來說,我會建議限制'shared_ptr'來表示_ownership_(比如一個Document擁有它的元素),而兄弟指針或者指向父容器的指針會是弱指針(或者原始指針) – Useless 2012-07-12 13:01:28

5

自動檢測帶有共享指針的循環引用是不可能的,我用來檢測循環引用的一種技術是以下列方式明確地進行。保持一個全局可訪問的std::vector< T* >,在所有ctors中將對象添加到向量中,然後在dtors中將其刪除。然後,在主結束時,您只需檢查該向量是否爲空,如果不是,則可能在某個地方有循環引用,向量將幫助您追蹤哪裏。如果共享靜態分配的對象所擁有的指針,則很容易出現誤報,特別是靜態初始化順序失敗時。

在boost中,定義了BOOST_SP_ENABLE_DEBUG_HOOKS,通過它可以針對所有類型對此應用程序進行廣泛的操作。

+0

你不需要重載new並刪除?超載也是一種選擇,對吧? – Baz 2012-07-12 11:17:17

+0

這也是一種選擇,但由於放置新的和自定義的分配器而不夠健壯。 – Ylisar 2012-07-12 15:42:45