我已经考虑了好几个小时,但仍然无法理解......这是链接列表的开源定义。
template <typename T>
class NPT_List
{
protected:
class Item;
public:
// types
typedef T Element;
class Iterator {
public:
Iterator() : m_Item(NULL) {}
explicit Iterator(Item* item) : m_Item(item) {}
Iterator(const Iterator& copy) : m_Item(copy.m_Item) {}
T& operator*() const { return m_Item->m_Data; }
T* operator->() const { return &m_Item->m_Data;}
Iterator& operator++() { // prefix
m_Item = m_Item->m_Next;
return (*this);
}
Iterator operator++(int) { // postfix
Iterator saved_this = *this;
m_Item = m_Item->m_Next;
return saved_this;
}
Iterator& operator--() { // prefix
m_Item = m_Item->m_Prev;
return (*this);
}
Iterator operator--(int) { // postfix
Iterator saved_this = *this;
m_Item = m_Item->m_Prev;
return saved_this;
}
operator bool() const {
return m_Item != NULL;
}
bool operator==(const Iterator& other) const {
return m_Item == other.m_Item;
}
bool operator!=(const Iterator& other) const {
return m_Item != other.m_Item;
}
void operator=(const Iterator& other) {
m_Item = other.m_Item;
}
void operator=(Item* item) {
m_Item = item;
}
private:
Item* m_Item;
// friends
friend class NPT_List<T>;
};
// methods
NPT_List<T>();
NPT_List<T>(const NPT_List<T>& list);
~NPT_List<T>();
NPT_Result Add(const T& data);
NPT_Result Insert(const Iterator where, const T& data);
NPT_Result Remove(const T& data, bool all=false);
NPT_Result Erase(const Iterator position);
NPT_Result PopHead(T& data);
bool Contains(const T& data) const;
NPT_Result Clear();
NPT_Result Get(NPT_Ordinal index, T& data) const;
NPT_Result Get(NPT_Ordinal index, T*& data) const;
NPT_Cardinal GetItemCount() const { return m_ItemCount; }
Iterator GetFirstItem() const { return Iterator(m_Head); }
Iterator GetLastItem() const { return Iterator(m_Tail); }
Iterator GetItem(NPT_Ordinal index) const;
// list manipulation
NPT_Result Add(NPT_List<T>& list);
NPT_Result Remove(const NPT_List<T>& list, bool all=false);
// item manipulation
NPT_Result Add(Item& item);
NPT_Result Detach(Item& item);
NPT_Result Insert(const Iterator where, Item& item);
// list operations
// keep these template members defined here because MSV6 does not let
// us define them later
template <typename X>
NPT_Result Apply(const X& function) const
{
Item* item = m_Head;
while (item) {
function(item->m_Data);
item = item->m_Next;
}
return NPT_SUCCESS;
}
template <typename X, typename P>
NPT_Result ApplyUntil(const X& function, const P& predicate, bool* match = NULL) const
{
Item* item = m_Head;
while (item) {
NPT_Result return_value;
if (predicate(function(item->m_Data), return_value)) {
if (match) *match = true;
return return_value;
}
item = item->m_Next;
}
if (match) *match = false;
return NPT_SUCCESS;
}
template <typename P>
Iterator Find(const P& predicate, NPT_Ordinal n=0) const
{
Item* item = m_Head;
while (item) {
if (predicate(item->m_Data)) {
if (n == 0) {
return Iterator(item);
}
--n;
}
item = item->m_Next;
}
return Iterator(NULL);
}
// operators
void operator=(const NPT_List<T>& other);
bool operator==(const NPT_List<T>& other) const;
bool operator!=(const NPT_List<T>& other) const;
protected:
// types
class Item
{
public:
// methods
Item(const T& data) : m_Next(0), m_Prev(0), m_Data(data) {}
// members
Item* m_Next;
Item* m_Prev;
T m_Data;
// friends
//friend class NPT_List<T>;
//friend class NPT_List<T>::Iterator;
};
// members
NPT_Cardinal m_ItemCount;
Item* m_Head;
Item* m_Tail;
};
我需要调用方法Detach以避免在列表超出范围时释放此列表的元素(我看到析构函数删除了所有元素)。 我的问题是:我该如何调用它?我无法创建Item的实例,因为类Item受到保护。那么,这个列表应该如何工作呢? 如果有必要,我当然可以修改列表,但我真的很感兴趣它应该如何工作,因为我正在尝试学习C ++,所以我想理解。
非常感谢您的帮助!
答案 0 :(得分:2)
这门课是胡说八道。您注意到自己没有看到如何拨打Detach()
,实际上我也看不到您如何拨打Detach()
。另外,一方面,protected
中有NPT_List
个成员,但另一方面,该类有一个非虚拟析构函数。这些是混合信息。和一个有这种特质的女孩(或者一个男人;检查什么适合你)一样,你应该远离它。
答案 1 :(得分:0)
你不能只从NPT_List继承,然后将Item推广到公众吗?
class FooList : public NPT_List<Foo>
{
public:
class Item;
...
}
答案 2 :(得分:0)
该类的接口不正确。 Add
,Detach
和Insert
应采用T&
参数,而不是Item&
。 Detach
还需要一个迭代器参数来指示要分离的元素。
修改:正如其他人所指出的,已有Add
和Insert
方法采用const T&
参数,因此这些其他方法可能都是为了受到保护。一个小错误。绊倒你的是缺少使用Detach
的{{1}}方法。它需要作为一种新方法添加:
T&
答案 3 :(得分:0)
使用Item
类型的方法是不应该成为公共接口一部分的实用方法。请改用Iterator
版本来访问相同的功能:
NPT_Result Add(const T& data);
NPT_Result Insert(const Iterator where, const T& data);
NPT_Result Erase(const Iterator position);