gpt4 book ai didi

c++ - 为用户定义的 MyList 重载 operator<<

转载 作者:行者123 更新时间:2023-11-28 07:34:11 28 4
gpt4 key购买 nike

我不能使用 std::list。目标是创建一个可以处理任何数据类型的用户定义的 MyList。我的问题出在我的嵌套迭代器类以及可能是我重载运算符 << 的函数上。我已经有一段时间了,但我被困住了。由于截止日期非常接近,我认为我应该冒着生命危险在这里提出问题。如果有人可以帮助我,那就太好了。

我意识到我的代码中存在内存泄漏,但这不是我目前主要担心的问题。我也意识到拥有这么多友元函数并不是一个好的编程习惯,我打算稍后使用 getData() 和 setData() 函数来获取/设置节点内的私有(private)变量。

所以请忽略以上2个问题...

错误信息:

"MyList.h", line 67: Error: iterator is not defined.

我将包含整个头文件,以防人们需要查看它。我将在错误所在的第 67 行添加注释。然后,我还将包括我的主要函数的一部分,该部分使用迭代器来展示我如何尝试设置迭代器并遍历列表。

#include<iostream>
#include<cstddef>

template<class T>
class Node
{
friend void MyList<T>::push_front(T aData);
friend void MyList<T>::push_back(T aData);
friend void MyList<T>::pop_front();
friend T MyList<T>::front();
friend void MyList<T>::print();
friend MyList<T>::~MyList();
friend std::ostream& operator<<(std::ostream&, Node<T>&);
private:
T data;
Node *next;
Node *prev;
public:
Node(T aData);

};

template<class T>
class MyList
{
Node<T> *head;
Node<T> *tail;
public:
MyList();
~MyList();
void push_front(T aData);
void push_back(T aData);
T front();
void pop_front();
void operator=(MyList<T>& another_List);

void print(); //Test function. Delete later.

class iterator
{
private:
MyList& object;
Node<T> *current;
public:
iterator(MyList<T>&, Node<T>*); // iterator a(*this, head);
// MyList<int>::iterator a = list.Begin();
iterator operator++(); // a++
iterator operator++(int); // ++a
iterator operator--();
bool operator!=(iterator);
friend std::ostream& operator<<(std::ostream&, iterator&);
};

iterator Begin();
iterator End();
};

template<class T>
std::ostream& operator<<(std::ostream& out, Node<T>& n)
{
out << *n.current << ' ';

return out;
}

template<class T>
std::ostream& operator<<(std::ostream& out, iterator& i) //ERROR
{
out << i->current << ' ';

return out;
}

template<class T>
Node<T>::Node(T aData)
{
data = aData;
}

template<class T>
MyList<T>::MyList()
{
head = NULL;
}

template<class T>
MyList<T>::~MyList()
{
Node<T> *temp;

while(head != NULL)
{
temp = head;
head = head->next;
delete temp;
}
head = NULL;
}

template<class T>
void MyList<T>::push_front(T aData)
{
if(head == NULL)
{
head = new Node<T>(aData);
head->next = tail;
head->prev = NULL;
tail->prev = head;
}
else
{
head->prev = new Node<T>(aData);
head->prev->prev = NULL;
head->prev->next = head;
head = head->prev;
}
}

template<class T>
void MyList<T>::push_back(T aData)
{
if(head == NULL)
{
head = new Node<T>(aData);
head->prev = NULL;
head->next = tail;
tail->prev = head;
}
else
{
tail->prev->next = new Node<T>(aData);
tail->prev->next->prev = tail->prev;
tail->prev->next->next = tail;
tail->prev = tail->prev->next;
}
}

template<class T>
T MyList<T>::front()
{
return head->data;
}

template<class T>
void MyList<T>::pop_front()
{
if(head == NULL)
std::cout << "The List is empty!" << endl;
else
{
head = head->next;
head->prev = NULL;
}
}

template<class T>
void MyList<T>::print()
{
while(head != NULL)
{
std::cout << "Test print function" << std::endl;
std::cout << '[' << head->data << ']' << std::endl;
head = head->next;
}
std::cout << "End of test print function" << std::endl;
}

template<class T>
MyList<T>::iterator::iterator(MyList<T>& list, Node<T>* p)
{
object = list;
current = p;
}

template<class T>
typename MyList<T>::iterator MyList<T>::iterator::operator++()
{
if(current == object.tail)
{
}
else
current = current->next;
return this;
}

template<class T>
typename MyList<T>::iterator MyList<T>::iterator::operator++(int)
{
if(current == object.tail)
{
}
else
current = current->next;
return this->prev;
}

template<class T>
typename MyList<T>::iterator MyList<T>::iterator::operator--()
{
if(current == object.head)
{
}
else
current = current->prev;
return this;
}

template<class T>
bool MyList<T>::iterator::operator!=(iterator b)
{
return (this.current == b.current);
}

template<class T>
typename MyList<T>::iterator MyList<T>::Begin()
{
return iterator(object, head);
}

template<class T>
typename MyList<T>::iterator MyList<T>::End()
{
return iterator(object, tail);
}

主要.cpp

   MyList<int>::iterator i = aList.Begin();
while(i != aList.End())
{
cout << i;
i++;
}

最佳答案

自你定义iterator类嵌套在您的 MyList 的定义中类模板,适用于外部的所有代码 MyList , 它的名字是 MyList<whatever>::iterator .

也许您在包含错误的代码中有一些稍微不同的意思。当您将其定义为模板时:

template<class T>
std::ostream& operator<<(std::ostream& out, iterator& i) //ERROR
{
out << i->current << ' ';

return out;
}

您似乎根本没有使用它的模板参数 ( T)。也许你真的想要更像:

template<class iterator>
std::ostream& operator<<(std::ostream& out, iterator& i) //ERROR
{
out << i->current << ' ';

return out;
}

在这种情况下,您不需要提供限定符,因为 iterator这里只是指模板参数。当您使用它时,编译器通常会推断出您实际传递的迭代器的类型。

请注意,像这样在模板参数中指定迭代器类别是不必要的,但有点传统,因此您通常会使用类似 OutIterator 的东西而不仅仅是 iterator对于模板参数。

虽然这并不是很通用 -- 特别是 ->current意味着它只会真正适用于您的特定迭代器类型。更典型的代码会重载 operator *对于迭代器类型,因此客户端代码将只取消引用迭代器。另请注意,迭代器通常被认为足够“轻量级”,因此它们通常按值传递,而不是按引用传递。

class iterator {
// ...
T operator*() { return *current; }
};

// ...
template<class OutIt>
std::ostream& operator<<(std::ostream& out, OutIt i)
{
out << *i << ' ';
return out;
}

关于c++ - 为用户定义的 MyList 重载 operator<<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17045863/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com