为链接列表建立条目类别

问题描述 投票:0回答:1

我有一个新项目,我正在为双向链接列表中的条目创建一个类。我使用的是面向对象的样式,对此我经验有限。构造函数和函数在单独的文件中定义。

头文件:

#ifndef LISTENTRY_H_JDP
#define LISTENTRY_H_JDP

#include "DATAClass.h"
#include <iostream>

using namespace std;

typedef DATAClass l;
typedef class LISTEntry *listptr;

class LISTEntry
{
  DATAClass data;
  listptr prev;
  listptr next;

public:
  LISTEntry();
  LISTEntry(DATAClass l);
  LISTEntry(LISTEntry &le);
  ~LISTEntry();

  LISTEntry getNext();
  void setNext();

  LISTEntry getPrev();
  void setPrev();

  DATAClass getData();
  void setData(DATAClass d);
};

#endif // LISTENTRY_H_INCLUDED

实施文件:

#include "LISTEntry.h"

LISTEntry::LISTEntry()
{
    data = data;
    prev = NULL;
    next = NULL;
}

LISTEntry::LISTEntry(DATAClass l)   //take an item of type l and convert it into a LISTEntry
{
    data = l;
    prev = NULL;
    next = NULL;
}

LISTEntry::LISTEntry(LISTEntry &le)
{
    data = le.getData();
    prev = le.getPrev();
    next = le.getNext();
}

LISTEntry::~LISTEntry()
{
}

LISTEntry LISTEntry::getNext()
{
    return *next;
}

void LISTEntry::setNext()
{
    next = new LISTEntry;
}

LISTEntry LISTEntry::getPrev()
{
    return *prev;
}

void LISTEntry::setPrev()
{
    prev = new LISTEntry;
}

DATAClass LISTEntry::getData()
{
    return data;
}

void LISTEntry::setData(DATAClass d)
{
    data = d;
}

问题是我的副本构造函数LISTEntry(LISTEntry&le)。到目前为止,我收到了错误:

无法将'LISTEntry'转换为'listptr {aka LISTEntry *}']

我也不确定get和set函数。我希望他们链接到列表中相同类型的新条目。我想我在构造函数中实现指针时遇到麻烦。有人可以帮忙吗?

c++ oop pointers linked-list doubly-linked-list
1个回答
1
投票

您可以通过删除复制构造函数来解决问题,但这掩盖了导致错误的问题。

除非l写得不好(违反the Rules of Three or Five),否则LISTEntry中不需要复制构造函数或析构函数。 LISTEntry本身没有特殊的资源,应该能够遵守零规则。如果l损坏,请修复l,不要在其他类上造成缺陷。

但是出于多种原因,这不是您想要执行的操作。

导致错误消息的根本问题是prev = le.getPrev();试图将源LISTEntry的先前节点的副本分配给指向先前节点的新LISTEntry的指针。

[prev需要LISTEntry的地址,而不是LISTEntry

在链接列表中,LISTEntry LISTEntry::getNext()LISTEntry LISTEntry::getPrev()几乎应该不返回所指向节点的副本。您要返回指针。否则,您会发现遍历链表是一次冒险。您将操作(可能会修改)节点副本而不是原始副本。混乱随之而来。

将它们更改为LISTEntry * LISTEntry::getNext()并删除return语句中的取消引用。

这解决了该错误,还有更多尚未找到的错误,但是却给您带来了另一个问题,如果删除了复制构造函数,则会遇到相同的问题。现在,您有两个LISTEntry,它们具有相同的prevnext。这可能会导致列表不稳定。使用副本,您可以将废话从原件清单中剔除。不酷小心。实际上,最好不要复制链接并创建复制构造函数:

LISTEntry::LISTEntry(const LISTEntry &le) // make everything const until proven otherwise
{
    data = le.data; // this is a member function so it can access private variables
                    // no need for the accessor function
    prev = nullptr;
    next = nullptr;
}

您还需要/想要一个赋值运算符

LISTEntry & operator=(const LISTEntry &le)
{
    if (this != &le)
    {
        data = le.data; 
        prev = nullptr;
        next = nullptr;
    }
}

您还应该讨论

void LISTEntry::setNext()
{
    next = new LISTEntry;
}

带有your rubber duck。 Ducky想知道,如果您总是创建一个新节点,您打算链接一个现有节点吗?这将使插入,删除和排序变得非常困难。


0
投票

您可以通过删除复制构造函数来解决问题,但这掩盖了导致错误的问题。

除非l写得不好(违反the Rules of Three or Five],在LISTEntry中不需要复制构造函数或析构函数。LISTEntry本身没有特殊资源,并且应该能够遵守零规则)如果l损坏,请修复l,不要在其他类上造成它的缺陷。

但是出于多种原因,这不是您想要执行的操作。

导致错误消息的根本问题是prev = le.getPrev();试图将源LISTEntry的先前节点的副本分配给指向先前节点的新LISTEntry的指针。

[prev需要LISTEntry的地址,而不是LISTEntry

在链接列表中,LISTEntry LISTEntry::getNext()LISTEntry LISTEntry::getPrev()几乎应该不返回所指向节点的副本。您要返回指针。否则,您会发现遍历链表是一次冒险。您将操作(可能会修改)节点副本而不是原始副本。混乱随之而来。

将它们更改为LISTEntry * LISTEntry::getNext()并删除return语句中的取消引用。

这解决了该错误,还有更多尚未找到的错误,但是却给您带来了另一个问题,如果删除了复制构造函数,则会遇到相同的问题。现在,您有两个LISTEntry,它们具有相同的prevnext。这可能会导致列表不稳定。使用副本,您可以将废话从原件清单中剔除。不酷小心。实际上,最好不要复制链接并创建复制构造函数:

LISTEntry::LISTEntry(const LISTEntry &le) // make everything const until proven otherwise
{
    data = le.data; // this is a member function so it can access private variables
                    // no need for the accessor function
    prev = nullptr;
    next = nullptr;
}

您还需要/想要一个赋值运算符

LISTEntry & operator=(const LISTEntry &le)
{
    if (this != &le)
    {
        data = le.data; 
        prev = nullptr;
        next = nullptr;
    }
}

您还应该讨论

void LISTEntry::setNext()
{
    next = new LISTEntry;
}

带有your rubber duck。 Ducky想知道,如果您总是创建一个新节点,您打算链接一个现有节点吗?这将使插入,删除和排序变得非常困难。

© www.soinside.com 2019 - 2024. All rights reserved.