0

可能重复:
在递归函数中创建 std::list of value 而不是 std::list of pointers

我有这堂课:

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

我建议您添加一个成员函数:

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 回答