重载运算符<<用于用户定义的 MyList
Overloading operator<< for user defined MyList
我不能使用std::list。目标是创建一个用户定义的MyList,它可以处理任何数据类型。我的问题是我的嵌套迭代器类和可能重载操作符<<的函数。我做这个已经有一段时间了,我被困住了。既然截止日期很近了,我想我应该冒险在这里问这个问题。如果有人能帮我做这件事就太好了。
我意识到我的代码中存在内存泄漏,但这不是我目前主要关心的问题。我也意识到,有这么多的朋友函数不是一个好的编程实践,我计划使用getData()和setData()函数来获取/设置节点内的私有变量。
所以请忽略以上两个问题…
错误信息:
"MyList.h", line 67: Error: iterator is not defined.
我将包括整个头文件,以便以防人们需要看到它。我将在错误所在的第67行添加注释。然后,我还将在main函数中包含一个使用迭代器的部分,以演示如何设置迭代器并遍历列表。
#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);
}
main.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
只是引用模板参数。当你使用this时,编译器通常会推断出你实际传递的迭代器的类型。
请注意,在模板形参中像这样指定迭代器类别是不必要的,但在某种程度上是传统的,因此您通常会使用类似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;
}
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 如何显式调用运算符<<
- 模板操作员&lt;未打电话
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 左角支架解释为操作员&lt;而不是模板参数
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- 超载操作员&lt;&lt; - 必须是二进制操作员
- 没有匹配的“运营商&lt;&lt;”