2016-02-17 6 views
-2

Im пишет класс HeapPriorityQueue с интеркатором. Проблема заключается в том, когда .begin() fuction вызывает конструктор Iterator, он переходит в конструктор назначения копирования для базового класса (класс HeapPriorityQueue). Я инициализировал все переменные, но когда они передают конструктор Iterator, они теряются. Я не понимаю, почему. Я попытался инициализировать их внутри тела, но отладчик не выполнил тело, которое, как я думал, было действительно странным.Конструктор итератора не инициализируется правильно

У меня только что убрали код достаточно, чтобы другие могли быстро понять. Единственное примечание, которое я хочу добавить, - это определить приоритет, в котором я использую gt() fucntion, или 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

Думаем, что нам нужно увидеть функцию «HeapPriorityQueue :: begin», но предпочтительнее MCVE. (Http://stackoverflow.com/help/mcve) – user4581301

+0

есть функция begin для итератора. –

+0

Итератору не должно быть копии HPQ! Почему ты бы так поступил? –

ответ

0

Я инициализируются все переменные, но когда они проходят Итератор Constructer они заблудились.

Переменные всегда инициализируются в порядке, они объявлены, так что давайте посмотрим на те:

//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.

Ваш отзыв: Writing your own STL Container.

+0

Я знаю, что мы должны избегать комментариев, таких как благодарность, но спасибо. Эта связь золотая. – user4581301

Смежные вопросы