这是我对双链表的某些方法的实现。但是我在实现自定义迭代器和Const_Iterators时遇到问题。
HPP文件为:
namespace pjc
{
class list
{
private:
struct node
{
double val = 0;
node *prev = nullptr;
node *next = nullptr;
};
node *head = nullptr;
node *tail = nullptr;
size_t num_elements = 0;
public:
class const_iterator
{
node *current_ptr = nullptr;
const list *o_list = nullptr;
public:
using difference_type = std::ptrdiff_t;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = const double;
using reference = const double &;
using pointer = const double *;
const_iterator() = default;
const_iterator(node *ptr, const list *gen);
const_iterator &operator++();
const_iterator operator++(int);
const_iterator &operator--();
const_iterator operator--(int);
reference operator*() const;
pointer operator->() const;
bool operator==(const const_iterator &rhs) const;
bool operator!=(const const_iterator &rhs) const;
friend class list;
};
class iterator
{
node *current_ptr = nullptr;
const list *o_list = nullptr;
public:
using difference_type = std::ptrdiff_t;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = double;
using reference = double &;
using pointer = double *;
iterator() = default;
iterator(node *ptr, const list *gen);
iterator &operator++();
iterator operator++(int);
iterator &operator--();
iterator operator--(int);
reference operator*() const;
pointer operator->() const;
operator const_iterator() const;
bool operator==(const iterator &rhs) const;
bool operator!=(const iterator &rhs) const;
friend class list;
};
list() = default;
list(const list &rhs);
list &operator=(const list &rhs);
list(list &&rhs);
list &operator=(list &&rhs);
~list();
.....
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
std::pair<list, list> split(const_iterator place);
void merge(list &rhs);
void sort();
bool operator!=(const list &lhs, const list &rhs);
bool operator>(const list &lhs, const list &rhs);
bool operator<=(const list &lhs, const list &rhs);
bool operator>=(const list &lhs, const list &rhs);
void swap(list &lhs, list &rhs);
我的.cpp文件是:
list::iterator list::begin() {
return list::iterator(head->next, this);
}
list::iterator list::end() {
return list::iterator(head->prev, this);
}
list::const_iterator list::begin() const {
return list::iterator(head->next, this);
}
list::const_iterator list::end() const {
return list::iterator(head->prev, this);
}
list::const_iterator list::cbegin() const {
return list::iterator(head->next, this);
}
list::const_iterator list::cend() const {
return list::iterator(head->prev, this);
}
list::list(const pjc::list &rhs) {
for (node *current_node = rhs.head; current_node != nullptr; current_node = current_node->next)
{
this->push_back(current_node->val);
}
}
list::const_iterator::const_iterator(list::node *ptr, const list *gen) {
this -> current_ptr = ptr;
this -> o_list = gen;
}
您可以检查此代码是否有错误和内存泄漏?我是C ++的新手。当我尝试实现Iterator begin(),end(),cbegin()atd的方法时。像这样
list::iterator list::begin() {
return list::iterator(head->next, this)
}
还有
list::iterator list::end() {
return list::iterator(head->prev, this);
}
我收到以下错误: 4 [main] tests-stage-2 11144 cygwin_exception :: open_stackdumpfile:将堆栈跟踪信息转储到tests-stage-2.exe.stackdump
在此测试中:
TEST_CASE("begin and end iterators of empty list are equal", "[stage2]") {
list l;
REQUIRE(l.begin() == l.end());
REQUIRE_FALSE(l.begin() != l.end());
REQUIRE(l.cbegin() == l.cend());
REQUIRE_FALSE(l.cbegin() != l.cend());
}
请向我解释我做错了什么?
非常感谢您!
答案 0 :(得分:1)
问题可能在于以下组合:
node *head = nullptr;
node *tail = nullptr;
之后
list::iterator list::begin() {
return list::iterator(head->next, this)
}
list::iterator list::end() {
return list::iterator(head->prev, this);
}
您已经创建了一个默认构造的list
,它将head
和tail
都初始化为nullptr
。然后,您创建引用head->next
和head->prev
的迭代器。
简而言之,您正在取消引用空指针。
通常,begin()
应该指向列表的开头(head
),而end()
应该指向列表的末尾(我不确定您如何表示在这种情况下,也许tail
需要成为前哨节点?)。
当前,begin()
指向如果有任何内容,则超过开始的位置,end
指向开始之前的位置,并且我不确定您的代码是否允许成为有效节点。
我不能说这是最好的解决方案,并且我还没有测试过,但是我可以尝试以下方法:
更改tail
:
Node tail{0, nullptr, nullptr};
Node *head = &tail;
还有begin
和end
:
list::iterator list::begin() {
return list::iterator(head, this)
}
list::iterator list::end() {
return list::iterator(&tail, this);
}
如果head
为空,则将head->next
设置为新节点,并将新节点的next
设置为tail
。我认为tail->prev
也可以指向新节点。然后,新节点将位于最后一个节点(tail->prev
和tail
)之间。