链接清单声明好吗?

时间:2015-12-22 22:19:50

标签: c++ list class pointers friend

我正在尝试首次实现LinkedList。我几乎完成了声明头文件,但是我得到了一个不会消失的小错误。我在Node类下面声明了LinkedList和Iterator类,我不断收到消息“将LinkedList重新定义为一种不同类型的符号”和“将Iterator重新定义为另一种符号”。我尝试在代码的最顶部声明​​类,如下所示,将友元函数移动到私有声明,但似乎没有任何工作。有人能指出我做错了什么。除了以下内容之外,我没有做太多其他事情。

class LinkedList;
class Iterator;


template <typename T>
class Node{
public:
    Node(T Data);


private:
    T data;
    Node* next;
    Node* previous;
    friend class LinkedList;  
    friend class Iterator;
};

template<typename T>
class LinkedList {
public:
    LinkedList();
    void pushback(T data); 
    //void insert(Iterator pos, T data);
    ~LinkedList();
    //Iterator begin();
    //Iterator end();

private:
    Node* first;
    Node* last;
    friend class Iterator;
};

template <typename T>
class Iterator{
public:

private:
    Node* position;
    LinkedList* container;
    friend class LinkedList;
};

#endif /* defined(__Linked_List_1__LinkedList__) */

3 个答案:

答案 0 :(得分:1)

首先将LinkedList声明为一个类,然后将LinkedList定义为类模板。您应该立即将名称声明为类模板(这同样适用于其他声明):

template <typename> class LinkedList;

当引用相应的类模板时,例如friend中的Node声明,您需要将类模板设为朋友,例如,使用

template <class S> friend class LinkedList;

......或者,最好使相应的实例化成为朋友:

friend class LinkedList<T>;

答案 1 :(得分:0)

您正在声明LinkedList是非模板化的。将其更新为:

template<typename T> class LinkedList;

Iterator做同样的事。

答案 2 :(得分:0)

当你实现LinkedList模板类时,你应该将typename T转发到Node类的声明中,因为Node是一个模板,它需要指定一个类型名来扩展特定类型的代码。

我的解决方案是使用嵌套类来解决一些复杂的依赖问题并为你做转发。(比如A类包含B类,B类包含A类)

namespace test{
  template<typename T> class Iterator;

  template<typename T>
  class LinkedList {
  public:
    LinkedList();
    void pushback(T& data);
    void insert(Iterator<T> pos, T& data);
    ~LinkedList();
    Iterator<T> begin();
    Iterator<T> end();
  private:

    struct Node{
      T data;
      Node* next;
      Node* prev;
    }; //Node should be expose to others, try not to complicate friendship

    Node* first;
  };

  template<typename T> class Iterator{
  public:
    T& operator*() const;
    T* operator->() const;
    Iterator<T> next();
  private:
    struct Node{
      T data;
      Node* next;
      Node* prev;
    };
    Node* position;
    LinkedList<T>* container;
    friend class LinkedList<T>;
  };
}

上面的代码向您展示了如何使用嵌套类(或结构,基本上struct是一个类)。您不会将节点暴露给用户,迭代器应该是类似指针。我更喜欢重载operator *和 - &gt;。

使用嵌套类是一件好事,因为很容易将类移出然后移入。当你认为可以使用嵌套类时,你应该尝试。