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
可以看到Node
s,我们可以将所有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
。