我正在用一个interator编写一个HeapPriorityQueue类。问题是当.begin()函数调用Iterator构造函数时,它进入基类的复制赋值构造函数(HeapPriorityQueue类)。我初始化了所有变量,但是当它们通过Iterator构造函数时,它们就会丢失。我不明白为什么。我尝试在体内初始化它们但调试器不会执行身体,我认为这很奇怪。
我只是将代码条带化得足够低,以便其他人可以快速理解。我要添加的唯一注释是为了确定我在模板中使用gt()函数或tgt的优先级。
感谢任何帮助,谢谢
template<class T, bool (*tgt)(const T& a, const T& b) = nullptr> class HeapPriorityQueue {
public:
//Destructor/Constructors
~HeapPriorityQueue();
HeapPriorityQueue (bool (*cgt)(const T& a, const T& b) = nullptr);
HeapPriorityQueue (const HeapPriorityQueue<T,tgt>& to_copy, bool (*cgt)(const T& a, const T& b) = nullptr);
class Iterator {
public:
//Private constructor called in begin/end, which are friends of HeapPriorityQueue<T,tgt>
~Iterator();
T erase();
std::string str () const;
HeapPriorityQueue<T,tgt>::Iterator& operator ++ ();
HeapPriorityQueue<T,tgt>::Iterator operator ++ (int);
friend Iterator HeapPriorityQueue<T,tgt>::begin () const;
friend Iterator HeapPriorityQueue<T,tgt>::end () const;
private:
//If can_erase is false, the value has been removed from "it" (++ does nothing)
HeapPriorityQueue<T,tgt> it; //copy of HPQ (from begin), to use as iterator via dequeue
HeapPriorityQueue<T,tgt>* ref_pq= nullptr;
int expected_mod_count=0;
bool can_erase = true;
//Called in friends begin/end
//These constructors have different initializers (see it(...) in first one)
Iterator(HeapPriorityQueue<T,tgt>* iterate_over, bool from_begin); // Called by begin
Iterator(HeapPriorityQueue<T,tgt>* iterate_over); // Called by end
};
Iterator begin () const;
Iterator end () const;
private:
bool (*gt) (const T& a, const T& b); // The gt used by enqueue (from template or constructor)
T* pq; // Array represents a heap, so it uses heap ordering property
int length = 0; //Physical length of pq array: must be >= .size()
int used = 0; //Amount of array used: invariant: 0 <= used <= length
int mod_count = 0; //For sensing concurrent modification
};
template<class T, bool (*tgt)(const T& a, const T& b)>
HeapPriorityQueue<T,tgt>::HeapPriorityQueue(const HeapPriorityQueue<T,tgt>& to_copy, bool (*cgt)(const T& a, const T& b))
: gt(tgt != nullptr ? tgt : cgt), length(to_copy.length) {
if (gt == nullptr)
gt = to_copy.gt;//throw TemplateFunctionError("HeapPriorityQueue::copy constructor: neither specified");
if (tgt != nullptr && cgt != nullptr && tgt != cgt)
throw TemplateFunctionError("HeapPriorityQueue::copy constructor: both specified and different");
pq = new T[length];
if (gt == to_copy.gt)
used = to_copy.used;
for (int i=0; i<to_copy.used; ++i)
enqueue(to_copy.pq[i]);
}
template<class T, bool (*tgt)(const T& a, const T& b)>
auto HeapPriorityQueue<T,tgt>::begin () const -> HeapPriorityQueue<T,tgt>::Iterator {
return Iterator(const_cast<HeapPriorityQueue<T,tgt>*>(this),true);}
template<class T, bool (*tgt)(const T& a, const T& b)>
HeapPriorityQueue<T,tgt>::Iterator::Iterator(HeapPriorityQueue<T,tgt>* iterate_over, bool tgt_nullptr):
it(*ref_pq),ref_pq(iterate_over),expected_mod_count(ref_pq->mod_count){}
答案 0 :(得分:0)
我初始化了所有变量,但是当它们通过Iterator构造函数时,它们就会丢失。
变量总是按照它们声明的顺序初始化,所以让我们看一下:
//If can_erase is false, the value has been removed from "it" (++ does nothing)
HeapPriorityQueue<T,tgt> it; //copy of HPQ (from begin), to use as iterator via dequeue
HeapPriorityQueue<T,tgt>* ref_pq= nullptr;
int expected_mod_count=0;
bool can_erase = true;
然后:
HeapPriorityQueue<T,tgt>::Iterator::Iterator(HeapPriorityQueue<T,tgt>* iterate_over, bool tgt_nullptr):
it(*ref_pq),ref_pq(iterate_over),expected_mod_count(ref_pq->mod_count){}
首先,您将it
初始化为*ref_pq
,即*nullptr
,这是非法的,通常会立即崩溃。我没有真正费心去分析这一点,但我确实有一个问题。为什么在世界上你的“指针”包含它试图迭代的整个数据集的副本?不要那样做。另外,我不知道你对expected_mod_count
的意图,但这可能也是一个坏主意。您的tgt
模板参数也是如此。