【问题标题】:c++ doubly linked list with null object modelc++ 具有空对象模型的双向链表
【发布时间】:2012-07-15 17:23:08
【问题描述】:

我正在尝试使用空对象模型创建双向链表。到目前为止,我已经实现了一个将节点添加到列表开头的方法和一个显示节点的方法。我的问题是显示功能总是显示0。谁能指出我哪里出了问题以及如何解决?另外,我在这里正确实现空对象模型是否正确?

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

编辑: 修复显示问题后,我有另一个:当调用 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;
}

【问题讨论】:

  • 您应该在调试器中逐行执行代码,以便在程序运行时检查变量的值。或者,您可以添加大量打印语句以达到类似的效果。例如,如果您在addHeadNode() 函数中检查foo-&gt;getData(),是否正确?

标签: c++ linked-list doubly-linked-list null-object-pattern


【解决方案1】:
elementNode(int element)
{
    node e;
    e.setData(element);
}

这段代码在做什么?您创建了节点 e,但它似乎随后被丢弃并且没有添加到任何列表中。

【讨论】:

    【解决方案2】:

    问题隐藏在

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

    这里发生了什么?首先创建node 类的实例,然后调用它的setData 成员函数。果然e 被修改为element 的值,但下一刻eelement 都消失了,因为它们被初始化的范围已经停止(由} 终止) 而element 中的信息尚未保存在任何地方。

    但是,如果将上面的代码替换为

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

    调用继承的setData成员函数,保存element的值,程序按预期输出5

    【讨论】:

    • 是的,这很有道理。谢谢!我还有一个问题我不明白。已编辑原始帖子。
    【解决方案3】:

    您的 elementNode 构造函数正在尝试初始化它的 node 部分:

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

    你实际上只是构造了一个不相关的节点然后丢弃它。

    你想要的是调用你的超类构造函数,这可以在子类构造函数的初始化列表中完成:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-11
      相关资源
      最近更新 更多