0

重複の可能性:
再帰関数で std::list of pointers の代わりに std::list of value を作成する

私はこのクラスを持っています:

class C
{
public:

    C* parent;
    std::list<C> children;
};

たとえば、このクラスを次のように使用できます。

C root;
C child;

root.children.push_back(child); // or other method of std::list (es: push_front, insert, ...)

// Here child.parent is root
// How can I set the parent of child?

の機能を失うことなく、クラスの内部でこの作業を行いたいのですstd::listが、可能ですか?

4

4 に答える 4

2

あなたの質問を正しく理解していれば、次のようなものが必要です。

class C {
public:
    C* parent;
    std::list<C *> children;
    explicit C(C *p = 0) : parent(p) {
        if (p) p->children.push_back(this);
    }
};

C root;
C child(&root);

childrenポインターを取るようにリストを変更したことに注意してください。Cノードのメモリを管理することが期待されていない限り、これは問題ありません。ノードを参照するだけです。

あなたの質問のタイトルは、 std::list が変更されたかどうかを知る方法です。あなたのコメントから、あなたが望むのはプロキシのようです:

class ListProxy {
    std::list<C *> children;
public:
    // replicate list traits
    // ...

    void push_back (C *c) {
        children.push_back(c);
        //... do something
    }

    void erase (iterator i) {
        children.erase(i);
        //... do something
    }

    //...
};

プロキシはリスト機能をリストに委譲しますが、リストを変更するメソッドの動作を拡張します。

class C {
public:
    C* parent;
    ListProxy children;
    explicit C(C *p = 0) : parent(p) {
        if (p) p->children.push_back(this);
    }
};
于 2012-07-07T08:07:57.093 に答える
1

クラスにインターフェイス関数を実装できます。例えば:

class C
{
private:
    std::list<C *> children;
public:
    C* parent;

    void AddChild(C *child);
};

次に、AddChild 関数でこれを行うだけです。

void C::AddChild(C *child)
{
     children.push_back(child);

     // Do internal work here...
}
于 2012-07-07T08:06:12.673 に答える
1

メンバー関数を 1 つ追加することをお勧めします。

class C
{
    C* parent;
    std::list<C> children;  //make it private first
public:
    void add_child(C const & child)
    {
         children.push_back(child);
         children.back().parent = this; //make `this` child's parent
    }    
};
于 2012-07-07T08:06:23.970 に答える
0

まず第一に、自分でリストをリンクしているように見えるのでAddChild、クラスにメソッドを追加するだけです。これは std::list 機能を使用できます。

リストに追加するたびにCをコピーしたくない可能性があるため、値ではなくCへのポインターを保存したいことは確かです。

public:
void AddChild(C *child)
{
    this.children.push_back(child);
}

次のように使用します。

C *root = new C();
C *child = new C();
child->parent = root;
root->AddChild(child);

AddChild で親を設定することもできます。これにより、首尾一貫したリストを作成できる可能性があります (各子には適切な親セットがあります)。

ただし、変更に関心がある場合は、オブザーバー パターンを使用してください。

これに関する記事は次のとおりです。C++ コード サンプルがそこに含まれています:オブザーバー パターン

于 2012-07-07T08:04:58.893 に答える