2012-10-13 104 views
4

我開始在我的qt工作中開始使用智能指針。讓我困惑的是,智能指針如何與Qt垃圾回收一起使用。整個Qt站在孩子QObject與QObject * parent構造成ctor參數的習慣用法上,因此可以實現垃圾收集。 例如:qt垃圾回收和智能指針

 QWidget* mWidget = new QWidget(this);//Here we not only 
              //ensure that mWidget will be deleted 
              //when its parent is deleted, but also tell qt, 
              //that mWidget is not a window, but belongs to 
              //parent's layout   

現在,如果我想換mWidget到智能指針。

typedef QScopedPointer<QWidget> WidgPtr; 
WidgPtr mWidget = WidgPtr(new QWidget(this)); 

但是現在當調用parent的dtor時,它會調用mWidget指針的delete兩次。首先由於垃圾收集,第二次當智能指針dtor被調用時。

當然,我們可以在沒有父項的情況下構造mWidget,然後更改某些標誌來關閉窗口行爲或調用setParent()(但隨後再次刪除mWidget)。但對我來說,做太複雜的初始化只是爲了能夠使用智能指針而不是原始指針。 或者我錯過了什麼? 謝謝。

+2

如果'QObject'子破壞機制有效,爲什麼你需要智能指針? – cmannett85

+0

由於智能指針提供了垃圾收集的一些優點。例如,如果在刪除父窗口部件之前引發異常,它們將防止內存泄漏。另一個例子是它們可以防止指針對象的意外複製等。 – Alexander

+2

對象所有權是* NOT *垃圾回收。 Qt中沒有GC,甚至沒有C++。 –

回答

4

QScopedPointerQSharedPointer並不知道它們的目標對象是存活還是死亡,所以如果你把智能指針保存在其他地方而不是成員變量中,那麼是的,在你的情況下,析構函數可能會被調用兩次。這就是爲什麼這些智能指針不適用於QObjects(但是當對象沒有父對象時,它們仍然很有用)。

如果你需要有人看守的指針保持到QObject,使用QPointer:一旦對象被銷燬它將成爲空,所以你可以在任何時候delete它,不用擔心造成混亂任意的。但請記住,QPointer不會銷燬析構函數中的引用對象。在大多數情況下,您應該構建QObjects的層次結構,並讓所有權系統清理內存。

+2

在Qt4中,比QPointer更喜歡QWeakPointer,以獲得更好的性能(請閱讀兩者的文檔)。在即將到來的Qt5中,我似乎記得QPointer再次正常,但不要聽我說... – hyde

+0

@hyde,感謝您的評論,我沒有意識到它:)顯然,這是真的:'QWeakPointer '雙打替代'QPointer'。我想知道他們爲什麼要保留'QPointer'呢? – Septagram