我正在研究一个双向列表类。我已经实现了一个Node类,它包含指向下一个元素的指针和指向前一个元素的指针以及一个数据部分(模板参数'Type'定义的类型)
最初,我将其实现为两个类。一个类定义了一个Node,另一个类定义了节点的链接列表(rList)。我想将Node类模板包含为rList的私有成员,因为Nodes应该隐藏在列表中并且只能由rlist管理。
Node类只有一个构造函数,用于初始化数据部分并将指针设置为null。
我试图将Node类放在rList类的私有部分中,但我似乎无法让组织正确。我遇到了语法错误。以下是我目前的实施情况。
template<typename Type>
class Node
{
Node* next;
Node* prev;
public:
Node(Type);
template<typename Type> friend class rList;
Type data;
};
template<typename Type>
Node<Type>::Node(Type d):data(d), next(0), prev(0)
{}
template<typename Type>
class rList
{
private:
Node<Type>* head;
Node<Type>* tail;
int size;
public:
rList<Type>();
~rList();
void push_front(const Type&);
void push_back(const Type&);
void insert(Node<Type>*, const Type&); //needs to be changed after merge
void erase(Node<Type>*); //needs to be changed after merge
void clear();
};
template<typename Type>
rList<Type>::rList():head(0), tail(0), size(0)
{}
template<typename Type>
rList<Type>::~rList()
{
clear();
}
template<typename Type>
void rList<Type>::clear()
{
while(head != 0)
{
Node<Type>* nextNode = head->next;
delete head;
head = nextNode;
}
}
template<typename Type>
void rList<Type>::push_front(const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = head;
head = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::push_back(const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
tail->next = newOne;
newOne->prev = tail;
tail = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::insert(Node<Type>* itr, const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = itr;
(itr->prev)->next = newOne;
newOne->prev = itr->prev;
itr->prev = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::erase(Node<Type>* itr)
{
if(itr == tail)
{
tail = itr->prev;
tail->next = 0;
delete itr;
}
else if(itr == head)
{
head = itr->next;
head->prev = 0;
delete itr;
}
else
{
(itr->prev)->next = itr->next;
(itr->next)->prev = itr->prev;
delete itr;
}
size--;
}
template<typename Type>
Node<Type>* rList<Type>::begin()
{
return head;
}
template<typename Type>
Node<Type>* rList<Type>::end()
{
return tail;
}
template<typename Type>
Node<Type>* rList<Type>::nextElem(Node<Type>* node)
{
return node->next;
}
我意识到这会破坏一些东西,因为Node *不能在rList类之外定义。我打算稍后使用迭代器类来更改它,以访问rList中的节点。但首先,如何使用这种类型的安排组织模板和成员函数定义?下面显示了我的尝试:
template<typename Type>
class rList //rList class template
{
private:
template<typename Type>
class Node //Node class template
{
Node* next;
Node* prev;
public:
Type data; //can be any POD type or class/struct
Node(Type);
template<typename Type> friend class rList; //so rList can access private Node pointers
};
Node<Type>* head;
Node<Type>* tail;
int size;
public:
rList<Type>();
~rList();
void push_front(const Type&);
void push_back(const Type&);
void insert(Node<Type>*, const Type&);
void erase(Node<Type>*);
clear();
};
template<typename Type>
rList<Type>::rList():head(0), tail(0), size(0)
{}
template<typename Type>
rList<Type>::~rList()
{
clear();
}
template<typename Type>
void rList<Type>::clear()
{
while(head != 0)
{
Node<Type>* nextNode = head->next;
delete head;
head = nextNode;
}
}
template<typename Type>
void rList<Type>::push_front(const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = head;
head = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::push_back(const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
tail->next = newOne;
newOne->prev = tail;
tail = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::insert(Node<Type>* itr, const Type& data)
{
Node<Type>* newOne = new Node<Type>(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = itr;
(itr->prev)->next = newOne;
newOne->prev = itr->prev;
itr->prev = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::erase(Node<Type>* itr)
{
if(itr == tail)
{
tail = itr->prev;
tail->next = 0;
delete itr;
}
else if(itr == head)
{
head = itr->next;
head->prev = 0;
delete itr;
}
else
{
(itr->prev)->next = itr->next;
(itr->next)->prev = itr->prev;
delete itr;
}
size--;
}
//constructor for Node
template<typename Type>
rList<Type>::Node<Type>::Node(Type d):data(d), next(0), prev(0)
{}
感谢您的投入!
*更新代码* 以下代码根据建议进行了修改。它正在发挥作用,似乎隐藏了适当的成员。请注意您注意到的任何改进! 再次感谢!!
template<typename Type>
class rList
{
private:
class Node
{
Node* next;
Node* prev;
public:
Type data;
Node(Type d);
template<typename Type> friend class rList;
};
Node* head;
Node* tail;
int size;
public:
rList<Type>();
~rList();
void push_front(const Type&);
void push_back(const Type&);
void insert(Node*, const Type&);
void erase(Node*);
void clear();
};
template<typename Type>
rList<Type>::rList():head(0), tail(0), size(0)
{}
template<typename Type>
rList<Type>::~rList()
{
clear();
}
template<typename Type>
void rList<Type>::clear()
{
while(head != 0)
{
Node* nextNode = head->next;
delete head;
head = nextNode;
}
}
template<typename Type>
void rList<Type>::push_front(const Type& data)
{
Node* newOne = new Node(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = head;
head = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::push_back(const Type& data)
{
Node* newOne = new Node(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
tail->next = newOne;
newOne->prev = tail;
tail = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::insert(Node* itr, const Type& data)
{
Node* newOne = new Node(data);
if(head == 0)
{
head = newOne;
tail = head;
}
else
{
newOne->next = itr;
(itr->prev)->next = newOne;
newOne->prev = itr->prev;
itr->prev = newOne;
}
size++;
}
template<typename Type>
void rList<Type>::erase(Node* itr)
{
if(itr == tail)
{
tail = itr->prev;
tail->next = 0;
delete itr;
}
else if(itr == head)
{
head = itr->next;
head->prev = 0;
delete itr;
}
else
{
(itr->prev)->next = itr->next;
(itr->next)->prev = itr->prev;
delete itr;
}
size--;
}
template<typename Type>
rList<Type>::Node::Node(Type d):data(d), next(0), prev(0)
{}