2012-07-15 65 views
1

我试图用空对象模型创建一个双向链接列表。到目前为止,我已经实现了一个将节点添加到列表开头的方法和一个显示节点的方法。我的问题是显示功能始终显示0.任何人都可以指出我出错的地方以及如何解决它?另外,我在正确的轨道上正确实现空对象模型吗?C++与空对象模型双向链接列表

注:这是一所学校分配。请不要在没有解释的情况下发布解决方案。我想了解和理解这里发生了什么。

编辑:修复显示问题后,我有另一个问题:当调用getHead()或getTail()列表为空或有节点时,它始终希望从节点类使用self()而不是nullNode类(如果列表为空)或elementNode类(如果列表中有节点)。我被困在如何解决这个问题上。

如果我打印出container.getNext()和container(对于一个空列表)的地址,两个地址是相同的,所以不应该添加 - > self()到最后调用self()方法nullNode类?

class node { 
public: 

    node(){/* Do nothing */} 

    node(int e){ element = e; } 

    int getData(){ return element; } 

    void setData(int e){ element = e; } 

    friend class list; 
protected: 
    node* getNext(){ return next; } 

    void setNext(node* n){ next = n; } 

    node* getPrev() { return prev; } 

    void setPrev(node* n){ prev = n; } 

    node* self(); 

private: 

    int element; 
    node* next; 
    node* prev; 
}; 

class nullNode : public node{ 
public: 
    nullNode(){/* Do nothing */} 

    int getData(){ return NULL; } 

    void setData(int e){ /* Do Nothing */ } 

    node* getNext(){ return head; } 

    void setNext(node* n){ head = n; } 

    node* getPrev() { return tail; } 

    void setPrev(node* n){ tail = n; } 

    node* self(){ return NULL; } 
private: 
    node* head; 
    node* tail; 
}; 

class elementNode : public node{ 
public: 
    elementNode(){/* Do nothing */} 

    elementNode(int element){ 
     setData(element); 
} 

    int getData(){ return node::getData(); } 

    void setData(int e){ node::setData(e); } 

    node* getNext(){ return node::getNext(); } 

    void setNext(node* n){ node::setNext(n); } 

    node* getPrev() { return node::getPrev(); } 

    void setPrev(node* n){ node::setPrev(n); } 

    node* self(){ return this; } 
}; 

class list{ 
public: 

    list(); 

    node* getHead(){ return (container.getNext())->self(); } 

    node* getTail(){ return (container.getPrev())->self(); } 

    node* addHeadNode(int e); 

    void removeNode(node* n); 

    void insertBefore(node* n, int e); 

    void insertAfter(node* n, int e); 

    void displayNode(node *n); 

private: 

    nullNode container; 
}; 

list::list() 
{ 
    container.setNext(&container); 
    container.setPrev(&container); 
} 

node* list::addHeadNode(int e) 
{ 
    node* foo = new elementNode(e); 

    foo->setPrev(&container); 
    foo->setNext(container.getNext()); 
    container.getNext()->setPrev(foo); 
    container.setNext(foo); 
    return foo; 
} 

void list::displayNode(node* n) 
{ 
    cout << "Node Data: " << n->getData() << endl; 
} 
int main() 
{ 
    list myList; 
    node* myNode; 
    myNode = myList.addHeadNode(5); 
    myList.displayNode(myNode); 

    return 0; 
} 
+0

你应该通过您的代码行由行调试步骤,以检查程序进行时变量的值。或者,您可以添加大量的打印语句以实现类似的效果。例如,如果您在'addHeadNode()'函数内检查'foo-> getData()',它是正确的吗? – 2012-07-15 17:27:44

回答

0
elementNode(int element) 
{ 
    node e; 
    e.setData(element); 
} 

这是什么代码在做什么?您创建节点e,但它似乎然后被扔掉,而不是添加到任何列表。在

elementNode(int element){ 
    node e; 
    e.setData(element); 
} 

这到底是怎么回事

0

问题隐藏?首先创建一个node类的实例,然后调用它的setData成员函数。果然e修改为值element,但下一时刻eelement都消失了,因为它们初始化的范围已停止结束(终止于}),而element中的信息尚未随处保存。

但是,如果与

elementNode(int element){ 
    setData(element); 
} 

它调用继承setData成员函数代替上面的代码,的element值被保存,并且如预期方案产出5

+0

是的,这很有道理。谢谢!我有另一个我不明白的问题。编辑原始帖子。 – Derek 2012-07-15 18:26:39

0

elementNode构造函数试图初始化它的node部分:

elementNode(int element){ 
    node e; 
    e.setData(element); 
} 

你实际上只是构建一个不相关的节点,然后将其丢弃。

你想要的是打电话给你的父类的构造,它可以在子类构造函数的初始化列表来完成:

elementNode(int element) : node(element) { 
}