2012-03-01 63 views
1

最佳方式,我有兩個類節點和NodeContainer:自我刪除的QObject

class Node: public QObject 
{ 
    NodeContainer* parent; 
} 

class NodeContainer : QObject 
{ 
    bool deleteChild(Node*child) 
    { 
     if(childNodes->remove(child)) 
     { 
      deleteLater(child); 
     } 
    } 

    QList<Node*> childNodes; 
} 

一個節點可以有一個父與否。 什麼是實現Node類的破壞更好的辦法:

1)訪問父,並從那裏

destroy() 
{ 
    if(parent !=0) 
    { 
     parent.deleteChild(this); 
    } 
    else 
    { 
     deleteLater(this); 
    } 
} 

2毀滅自己)發出信號,讓家長消滅它後

destroy() 
{ 
    if(parent !=0) 
    { 
     //Once the parent receives it, the parent will delete the child. 
     emit parentYouHaveToDeleteChild(this); 
    } 
    else 
    { 
     deleteLater(this); 
    } 
} 
+0

如果子節點通過'deleteLater'銷燬,父節點就會掛鉤其子節點的'destroy'信號並設置指針。那麼不需要檢查父母。此外,你的計劃看起來很奇怪。你確定這就是你想要的嗎? – pmr 2012-03-01 19:28:37

+0

我正在做一個小文本編輯器(帶標籤)。如果標籤被認定爲必須銷燬,則需要詢問包含標籤的標籤以將其刪除。作爲例子( Bla bla more bla bla)。如果決定刪除,它必須要求tag1將其從子女名單中刪除。 – Anton 2012-03-01 19:32:49

+0

您確定不想使用['QDomDocument'](http://qt-project.org/doc/qt-4.8/qdomdocument.html)而不是編寫自己的數據結構嗎? – alexisdm 2012-03-03 03:07:10

回答

1

如果parentYouHaveToDeleteChild信號連接到deleteChild插槽,那麼您所呈現的兩種方法之間實際上沒有區別。在調用插槽之前,程序不會返回到事件循環。

除了第二種方法增加信號/時隙調用的開銷。

0

使用智能指針

class Node: public QObject 
{ 
    std::unique_ptr<Node> parent; 
} 

如果作爲登錄到父指針時,它會刪除銷燬,如果你不那麼什麼都不會發生:)

我還建議在使用列表中的智能指針太:

std::list<std::unique_ptr<node> > node_list; 

可以typedeffed到

typedef std::unique_ptr<node> node_up_t; 
typedef std::list<node_up_t> node_list_t; 

或更好的東西

這樣,當元素從列表中會自動被刪除刪除,同樣是LIS的時候真t是毀滅。

對於非UI代碼,我強烈建議您使用標準容器,因爲它們是標準容器,並減少了對庫的依賴。

+0

它更多的是關於如何objet必須通知父母關於其刪除,然後關於如何刪除對象本身。 – Anton 2012-03-01 19:34:36

+0

這聽起來像是倒車設計,確定父母應該擁有孩子,父母應該告訴孩子它將被銷燬。 – 111111 2012-03-01 19:57:24

1

Object Trees and ownership

您也可以刪除子對象自己,他們會從他們的父母自行拆除。例如,當用戶移除工具欄時,它可能會導致應用程序刪除其QToolBar對象之一,在這種情況下,工具欄的QMainWindow父級將檢測到該更改並相應地重新配置其屏幕空間。

您從QObject派生Node和NodeContainer。 QObject已經有parent()函數和內置的object tree,用於自動刪除孩子或從父母中刪除已刪除的孩子。簡單地利用現有的機制,而不是重新發明輪子。

+0

但他的節點本身存儲對象,不使用QObject父存儲機制。而且,由於所有必須執行的投射,使用QObject父機制來管理樹木可能非常乏味。 – pmr 2012-03-01 20:48:28

+0

@pmr:「他的節點」不需要存儲父對象,因爲它可以通過'QObject :: parent()'來訪問。無論「乏味」如何,重用現有機制比實施其他機制花費的時間要少。此外,演員可以包裝成內聯方法或兩個。 – SigTerm 2012-03-01 22:00:11

0

我會做1),但在節點的析構函數,即

class Node: public QObject 
{ 
public: 
    ~Node() 
    { 
     if(parent !=0) 
     { 
      parent.deleteChild(this); 
     } 
    } 

    NodeContainer* parent; 
} 

我不認爲這是一個對象,以「自殺」好的OO實踐。創建Node的對象也應該刪除它們,並且通過析構函數,它們也將從其潛在的NodeContainer中移除。

請注意,如果您不使用信號/插槽或者Qt父母機制,那麼使您的對象成爲QObject的後代沒有多大意義。它增加了沒有好處的開銷。