为什么T是未定义的?我正在尝试实现一个用于双链表的节点类,它不喜欢我使用友元运算符后的T

Why is T undefined? I am trying to implement a node class to use for a doubly linkedlist and it does not like the T after I use the friend operator

本文关键字:链表 节点 运算符 友元 用于 不喜欢 未定义 为什么 实现 一个      更新时间:2023-10-16
class Node{
template<class T>
friend class DLList; 
private:
T data;
Node* next;
Node* prev;
public:
Node():next(nullptr),prev(nullptr){}
Node(T val):next(nullptr),prev(nullptr),data(val){}
Node(const Node<T>& rhs):next(nullptr),prev(nullptr),data(rhs.data){}
~Node();
};

我一直得到T是一种未知类型,请向我解释原因。

使用

class Node{
template<class T>
friend class DLList; 

唯一被模板化的是朋友。Node未被模板化。

解决方案:使节点成为模板以及

template<class T>
class DLList; // declare DLList is a template so that it's a template when friended
template<class T>
class Node{
friend class DLList<T>; // Node is now a friend of DLList<T> and no other DLLists 
private:
T data;
Node* next;
Node* prev;
public:
Node():next(nullptr),prev(nullptr){} // I don't recommend having this constructor.
// If T doesn't have a default constructor, 
// the program will not compile and the error 
// messages can be quite inscrutable.
Node(T val):data(val), next(nullptr),prev(nullptr){}
// I moved data to the front of the line because 
// the members are always initialized in the 
// same order as they are defined no matter the 
// order they are in in the initializer list. It 
// doesn't matter here, but I see it as a 
// sanitation issue.
Node(const Node<T>& rhs):data(rhs.val), next(nullptr),prev(nullptr){}
// corrected this constructor to use the correct 
// input value. I don't recommend having this 
// constructor. 1) You Probably don't need it. 
// the default constructor should be good enough
// and 2) this isn't really a copy. 
~Node();
};
template<class T>
class DLList // now we define DLList for real.
{
};

但是。。。有更好的方法可以做到这一点。

我们可以使Node成为DLList类的私有成员。现在只有DLList可以看到Nodes,我们可以将所有Node成员设为public

template<class T>
class DLList
{
private:
class Node{
public:
T data;
Node* next;
Node* prev;
Node(const T & val):data(val), next(nullptr),prev(nullptr){}
Node(const T & val,  Node* p, Node* n):data(val), next(p), prev(n){}
// Having a constructor that sets the prev and 
// next pointers makes insertion logic just a 
// bit easier later.
~Node();
};
// private DLList stuff goes here
public: 
// public DLList stuff goes here
};

为什么这是个好主意?封装。DLList之外的任何人都不应该知道Node的存在。他们当然不应该被允许拿到一个。有些白痴可能会在没有正确移除的情况下delete。他们可能会不小心把它弄碎。不要给他们机会。给他们迭代器并给他们数据。永远不要给他们Node