2012-07-07 124 views
0

可能重複:
Create std::list of value instead of std::list of pointers in recursive function如何知道是否一個std ::列表已被修改

我有這個類:

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的功能,是否有可能?

+3

請注意,您正在推送「child」的副本。 – ybungalobill 2012-07-07 08:02:05

+0

@ybungalobill是你是正義的,我想設置插入列表中的孩子的父母 – Nick 2012-07-07 08:05:57

+0

請匹配標題和您的實際問題。 – Arne 2012-07-07 08:06:10

回答

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++代碼示例包含有:Observer pattern

+0

他的名單是'C'類型不是'C *' – mathematician1975 2012-07-07 08:06:32

+0

想他想改變這個。你怎麼看? – 2012-07-07 08:08:16

+0

很可能,我只是覺得你應該提到你已經改變了他的列表中的對象的類型。 – mathematician1975 2012-07-07 08:09:36

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... 
} 
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 
    }  
}; 
+0

以這種方式我鬆了std :: list – Nick 2012-07-07 08:07:19

+0

@Nick的所有功能:您可以公開這些函數作爲成員函數。我認爲這樣做會更好,因爲除了添加新的功能之外,它還使您有機會爲他們選擇正確的名稱(這也很重要),例如我的答案中顯示的名稱。 – Nawaz 2012-07-07 08:09:52

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); 
    } 
}; 
+0

如果我添加'add_child'方法,我放棄了'std :: list'的所有功能,如果我將它設爲私有的,並且如果我不這樣做,我總是可以使用'push_back'方法並且使我的數據結構無效。 – Nick 2012-07-07 08:35:10

+1

@尼克:我不確定你的擔心是什麼。你是否害怕其他程序員訪問'children'列表並惡意添加子項? – jxh 2012-07-07 08:51:55

+0

@尼克:我更新了答案。問候 – jxh 2012-07-07 09:12:58