C ++继承设计链表

时间:2009-12-02 18:56:21

标签: c++ inheritance linked-list

我想创建一个继承自List类的链表类ListList。 ListList使用List中的函数,但具有自己的函数。它有自己的开始指针,指向列表的开头,以及它自己的Node结构,它包含不同数量的元素。

但是,看起来,当从ListList调用List的一个函数时,List使用它自己的开始指针和Node。但是我想要使用ListList的开始指针和Node。 有人可以帮我解决这个问题吗? 我可以发布一些代码,但我不知道哪些部分是相关的......

这是我在上面列出的名单

class LinkList
{
public:
LinkList(); //constructor that sets the start pointer to NULL, to show that the list is empty
~LinkList(); //destructor that deletes each node in the linked list
LinkList(const LinkList &original); //copy constructor
void addToken(string token); //creates a node with the given token and places it at the beginning of the linked list
string showList(); //returns a string of tokens, separated by commas and spaces
bool findToken(string token); //searches linked list for the given token, returns true if the token is in the list
string getToken(string word); //searches linked list for a token that begins with the given word.
                              //Returns the full token if there's a token that begins with the given word, else returns an empty string
void deleteList();
protected:

struct Node //each node of the linked list, held together by the next pointer
{
    string token;
    bool second_word; //tells whether or not there is a space within the token (a two-word keyword)
                      //This could be easily changed to an int that tells how many words are within the keyword (for multi-word keywords)
    Node *next; //pointer to the next node of the linked list. NULL if there is no next node
};

Node *start; //pointer to the beginning of the linked list, and the last added node
bool twoWordToken(string token); //returns true if there is a space located within a token, meaning the token consists of two words.
};

这是我在上面名为ListList的那个

class LinkListList: public LinkList
{
public:
LinkListList(); //modified contructor initiates the pointers start and ptrNode
~LinkListList(); //modified destructor deletes all nodes and secondaryList nodes
LinkListList(const LinkListList &original); //copy constructor
bool addSubList(LinkList subList, string commandWord); //calls setPtrNode, then adds the given subList to that node
bool findSubToken(string commandWord, string token); //calls setPtrNode, then calls on that node's secondaryList's findToken function
                                                     //returns true if the findToken function returns true, else returns false
string showSubList(string commandWord); //returns a string of tokens, separated by commas and spaces, representing the subList of the given token
string getSubToken(string word, string commandWord); //searches commandWord's subList for a token that begins with the given word.
                                              //Returns the full token if there's a token that begins with the given word, else returns an empty string
private:

struct Node //each node of the linked list, held together by the next pointer
{
    string token;
    bool second_word; //tells whether or not there is a space within the token (a two-word keyword)
    LinkList secondaryList; //keeps a list of all related words
    Node *next;
};

Node *start; //pointer to the beginning of the linked list
Node *ptrNode; //this pointer is used for the functions
void setPtrNode(string token); //sets ptrNode to point to the node containing the specified token. ptrNode is NULL if the token could not be found  
};

4 个答案:

答案 0 :(得分:3)

编辑:我明白了。

理想情况下,您只有一个链接列表实现可以包含任何类型的值,包括 - 这里是踢球者 - 一个复合数据结构,其链接列表作为其中一个字段。在你现在的代码中,实际上,继承实际上是不必要的,你通常会复制创建链表的所有艰苦工作,并且你将链表数据结构与你的更高级别混合在一起表示各种单词列表的对象。

这里有一种可能的方法来构建数据结构:

  • 通用链表:

    template <typename T>
    class LinkedList { ... };
    
  • 使用链接列表表示您正在制作的单词列表的类:

    class TokenList {
      struct Token {
        string word;
        LinkedList<string> related;
      };
      LinkedList<Token> list;
      // Methods to add/search/remove tokens from the lists and sublists
    };
    

(另外,我怀疑你实际寻求的数据结构是map,但这是另一个讨论。)

答案 1 :(得分:2)

看起来您正在寻找Has-A关系,而不是Is-A关系。

我建议你的LinkListList有一个第一种类型的列表列表,而不是使用继承。

答案 2 :(得分:0)

我认为你的List类需要一些虚函数。它对ListList一无所知,因此很难期望使用派生类的成员。

答案 3 :(得分:0)

基类中的虚函数允许继承者提供它的覆盖。当基类(或外部调用者将其视为基类)在派生实例中调用该函数时,它知道在派生类中查找该重写而不是使用基类中的重写。

如果您控制基类List类(而不是提供的框架类),您可以重构它以在关键位置使用虚函数,以便派生的ListList类可以将它们重定向到它自己的逻辑,同时仍然可以访问代码它作为一个列表 - 例如,您可以创建一个ListList并将其传递给期望List的东西。

但是如果你不能改变List并且它还没有你可以覆盖的虚拟功能,你可能无法做到。您可能必须查找不同的(较低的)基类,或者将ListList(或LinkedList?)创建为单独的类而不是派生类。它可以提供一个ToList()函数来将其内容导出为标准List(以及一个构造函数,它将List和/或From(List)函数从List导入回ListList)。但是,以这种方式使用它可能需要更多的工作,这取决于你实际需要做什么,而你首先想要从List派生出来。

编辑:根据您现在发布的代码,看起来继承可能不是您真正需要的,毕竟,正如@rmn指出的那样。因此,虽然这个答案希望能够解释一下虚拟功能如何工作(适用于最初提出的问题),但它可能不适用于您真正想要对这两个类进行的操作。