2012-03-01 28 views
1

私は2つのクラスのノードを持っているとNodeContainer:最適な方法

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

'子孫の' destroyed'シグナルまで親のフックを持ち、子が 'deleteLater'によって破壊された場合はポインタを設定します。親をチェックする必要はありません。また、あなたの計画は本当に奇妙に見えます。あなたはそれがあなたが望んでいると確信していますか? – pmr

+0

私は小さなテキストエディタ(タグ付き)を作っています。タグが破壊されなければならないと判断した場合、それを削除するにはtagを含むタグを要求する必要があります。一例として(Baab1ba)。 が削除されることを決定した場合、タグ1にその子リストから削除するように要求する必要があります。 – Anton

+0

あなた自身のデータ構造を書くのではなく、['QDomDocument'](http://qt-project.org/doc/qt-4.8/qdomdocument.html)を使いたくないですか? – alexisdm

答えて

1

parentYouHaveToDeleteChild信号がdeleteChildスロットに接続されている場合、提示した2つの方法の違いはありません。プログラムはスロットを呼び出す前にイベントループに戻りません。

ただし、2番目の方法では、信号/スロットコールのオーバーヘッドが追加されます。

0

あなたとならば、スマートポインタ

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

を使用します親に署名し、それは破壊に削除されるポインタ、あなたは何も:)

を起こりませんしていない場合、私は、あまりにも、リスト内のスマートポインタを使用することをお勧めします:

typedeffedすることができ
std::list<std::unique_ptr<node> > node_list; 

このよう

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

か何かより良い

に、要素は、それが自動的に削除されます、リストから削除されたときに、同じことがときLISの真実でありますtは破壊される。

UI以外のコードの場合、標準のコンテナを使用することを強くおすすめします。これは標準であり、ライブラリへの依存を減らすためです。

+0

これは、オブジェクトの削除について親オブジェクトにオブジェクトを削除する方法を通知する方法についてです。 – Anton

+0

これは後方のデザインのように聞こえますが、親が子を所有していることを確認してください。親は子が破壊されることを子供に伝える必要があります。 – 111111

1

Object Trees and ownership

また、子供が自分でオブジェクトを削除することができ、そして、彼らは彼らの両親から身を削除します。たとえば、ユーザーがツールバーを削除すると、アプリケーションがそのQToolBarオブジェクトの1つを削除することがあります。この場合、ツールバーのQMainWindow親はその変更を検出し、それに応じて画面スペースを再設定します。

QObjectからNodeおよびNodeContainerを派生させます。 QObjectはすでにparent()の機能を持ち、子を自動的に削除したり、削除した子を親から削除したりするために組み込まれたobject treeを持っています。ホイールを改造するのではなく、既存のメカニズムを利用するだけです。私は1)が、ノードのデストラクタで行うだろう

+0

しかし、彼のノードはオブジェクト自体を格納しており、QObject親ストレージメカニズムは使用しません。また、QObject親メカニズムを使用してツリーを管理すると、実行する必要があるすべてのキャストが面倒になることがあります。 – pmr

+0

@pmr: "彼のノード"は 'QObject :: parent()'でアクセスできるので、親オブジェクトを格納する必要はありません。既存のメカニズムを再利用することは、「面倒さ」に関係なく、別の実装よりも時間がかかります。さらに、キャストはインラインメソッドまたは2つにラップすることができます。 – SigTerm

0

、すなわち

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

    NodeContainer* parent; 
} 

私はそれが「自殺」するオブジェクトのための優れたオブジェクト指向の練習ではないと思います。ノードを作成するオブジェクトもノードを削除する必要があり、デストラクタを使用すると、それらも潜在的なNodeContainerから削除されます。

シグナル/スロットやQt子育てのメカニズムを使用しない場合は、QObjectの子孫を作成することはほとんどありません。利点なしでオーバーヘッドが増えます。

関連する問題