operator++ 重载如何迭代我的 LinkedList
How does operator++ overloading work to iterate over my LinkedList
这是我的 LinkedList 命名空间
namespace LinkedList {
template<class T>
class Node{
public:
Node(const T& data)
:data_(data), next_(nullptr) {}
T data_;
Node<T> *next_;
Node<T> *operator++(){
return next_;
}
};
template<class T>
class LinkedList{
public:
LinkedList()
: head_(nullptr), tail_(nullptr) {}
~LinkedList(){
Node<T> *curr = head_;
Node<T> *next;
while(curr != nullptr){
next = curr->next_;
delete curr;
curr = next;
}
}
void Append(const T& data) {
Node<T> *tmp = new Node<T>(data);
if(head_ == nullptr) {
head_ = tmp;
tail_ = tmp;
} else if(head_ == tail_){
head_->next_ = tmp;
tail_ = tmp;
} else {
tail_->next_ = tmp;
tail_ = tmp;
}
}
void Present(){
for(Node<T> *curr = head_; curr != nullptr; curr=curr->next_){
std::cout << curr->data_ << std::endl;
}
}
Node<T> *begin(){
return head_;
}
Node<T> *end(){
return nullptr;
}
private:
Node<T> *head_;
Node<T> *tail_;
};
}
我正在阅读迭代器并想让我的 LinkedList 对象与基于范围的 for 循环兼容。这是我从阅读基于范围的 for 循环中得到的
for(auto x: list){ }
等同于
for(; begin != end; ++begin) { //*begin};
我以为我很厚颜无耻,可以跳过几个运算符重载 (!=, *) 的步骤,让我的 LinkedList 可以通过将我的迭代器编程到我的节点 class 中来使用基于范围的 for 循环 for no除此之外还有其他原因,我喜欢它。这只是我学习 C++ 的第二天,所以这可能是一个愚蠢的问题,但我仍然对为什么这不起作用感到困惑:
LinkedList::LinkedList<int> list;
list.Append(3);
list.Append(5);
for(auto x: list) { //blah blah blah}
我知道我的前缀增量是核心问题,当for循环执行++__begin时,我希望它做的是___begin=_开始->next 但是它没有。为什么是这样?在我看来,运算符重载的工作方式是,无论我在重载函数中引用什么成员变量,它都是从我正在操作的实例中引用的。当我 return ptr 时,它正在将我正在操作的任何实例设置到这个 ptr。我知道我对此的理解是错误的,因为它不起作用,所以请有人向我解释它实际上是如何工作的,哈哈。
您写了一个
template<class T>
Node<T>* Node<T>::operator++();
会像
一样被调用
Node<int> n;
Node<int> *p = ++n; // calls the pre-increment operator
请注意,这与 canonical form
完全不同
Node<T>& Node<T>::operator++();
其中 returns 对可在表达式中使用的递增对象的引用。
但还有另一个问题:operator overloading 有效
When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, ...
但是 Node<T>*
不是 class 类型。它是一个指针,指针已经有自己的内置运算符。你不能超载他们。没有Node<T>*::operator++()
.
写一个迭代器。还不错,而且它们确实有效!
注意。迭代器旨在泛化指针,并具有兼容的接口。如果您的容器基本上是一个数组,您可以使用原始指针 - 因为递增指针已经是迭代数组的正确方法。
只有当我们想要提供对非连续结构的类似数组或类似指针的访问时,我们才需要做这些额外的工作。
这是我的 LinkedList 命名空间
namespace LinkedList {
template<class T>
class Node{
public:
Node(const T& data)
:data_(data), next_(nullptr) {}
T data_;
Node<T> *next_;
Node<T> *operator++(){
return next_;
}
};
template<class T>
class LinkedList{
public:
LinkedList()
: head_(nullptr), tail_(nullptr) {}
~LinkedList(){
Node<T> *curr = head_;
Node<T> *next;
while(curr != nullptr){
next = curr->next_;
delete curr;
curr = next;
}
}
void Append(const T& data) {
Node<T> *tmp = new Node<T>(data);
if(head_ == nullptr) {
head_ = tmp;
tail_ = tmp;
} else if(head_ == tail_){
head_->next_ = tmp;
tail_ = tmp;
} else {
tail_->next_ = tmp;
tail_ = tmp;
}
}
void Present(){
for(Node<T> *curr = head_; curr != nullptr; curr=curr->next_){
std::cout << curr->data_ << std::endl;
}
}
Node<T> *begin(){
return head_;
}
Node<T> *end(){
return nullptr;
}
private:
Node<T> *head_;
Node<T> *tail_;
};
}
我正在阅读迭代器并想让我的 LinkedList 对象与基于范围的 for 循环兼容。这是我从阅读基于范围的 for 循环中得到的
for(auto x: list){ }
等同于
for(; begin != end; ++begin) { //*begin};
我以为我很厚颜无耻,可以跳过几个运算符重载 (!=, *) 的步骤,让我的 LinkedList 可以通过将我的迭代器编程到我的节点 class 中来使用基于范围的 for 循环 for no除此之外还有其他原因,我喜欢它。这只是我学习 C++ 的第二天,所以这可能是一个愚蠢的问题,但我仍然对为什么这不起作用感到困惑:
LinkedList::LinkedList<int> list;
list.Append(3);
list.Append(5);
for(auto x: list) { //blah blah blah}
我知道我的前缀增量是核心问题,当for循环执行++__begin时,我希望它做的是___begin=_开始->next 但是它没有。为什么是这样?在我看来,运算符重载的工作方式是,无论我在重载函数中引用什么成员变量,它都是从我正在操作的实例中引用的。当我 return ptr 时,它正在将我正在操作的任何实例设置到这个 ptr。我知道我对此的理解是错误的,因为它不起作用,所以请有人向我解释它实际上是如何工作的,哈哈。
您写了一个
template<class T>
Node<T>* Node<T>::operator++();
会像
一样被调用Node<int> n;
Node<int> *p = ++n; // calls the pre-increment operator
请注意,这与 canonical form
完全不同Node<T>& Node<T>::operator++();
其中 returns 对可在表达式中使用的递增对象的引用。
但还有另一个问题:operator overloading 有效
When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, ...
但是 Node<T>*
不是 class 类型。它是一个指针,指针已经有自己的内置运算符。你不能超载他们。没有Node<T>*::operator++()
.
写一个迭代器。还不错,而且它们确实有效!
注意。迭代器旨在泛化指针,并具有兼容的接口。如果您的容器基本上是一个数组,您可以使用原始指针 - 因为递增指针已经是迭代数组的正确方法。
只有当我们想要提供对非连续结构的类似数组或类似指针的访问时,我们才需要做这些额外的工作。