Прямой итератор в стеке - PullRequest
       3

Прямой итератор в стеке

0 голосов
/ 06 сентября 2018

Я должен реализовать прямой итератор в стеке на основе массивов. Я не могу использовать std :: vectors или что-то еще, мне просто нужно это. Моя разработка этой программы остановилась, когда я начал с прямого итератора, и в частности с операторами.

У меня есть метод, который принимает общую последовательность, и из этого, учитывая смещение, создает стек:

template <typename IterT>       
  stack(IterT begin, IterT end) : _stack(0), _size(0), _capacity(0) {
    try {       
        for(; begin!=end; ++begin) {
            push(static_cast<T>(*begin));       
        }
    }
    catch(...) {
        clear();   //my method to destroy the stack 
        throw;
    }
}

В основном я делаю следующее:

int a[5] = {1, 2, 3, 4, 5};
stack<int> sint(a, a+5);
cout << sint << endl;

Но когда код запускается, стек создается, но не печатается. Кто-нибудь может мне помочь? А также дайте мне другие подсказки (по отступам кода, улучшениям и т. Д.). Спасибо, я опубликую код итератора вперед.

 class const_iterator {
    const T* data;
    unsigned int index;
public:
    typedef std::forward_iterator_tag iterator_category;
    typedef T                         value_type;
    typedef ptrdiff_t                 difference_type;
    typedef const T*                  pointer;
    typedef const T&                  reference;

    const_iterator() : data(0){}

    const_iterator(const T* arr) : data(arr) {}

    const_iterator(const const_iterator &other) 
        : data(other.data){ }

    const_iterator& operator=(const const_iterator &other) {
        data = other.data;
        return *this;
    }

    ~const_iterator() {
        data = 0;
    }

    reference operator*() const {
        return *data;
    }

    pointer operator->() const {
        return &(data);
    }

    const_iterator operator++(int) {
        const_iterator tmp(*this);
        ++*this;
        return tmp;
    }

    const_iterator& operator++() {
        ++data;
        return *this;
    }

    bool operator==(const const_iterator &other) const {
        return data[index] == other.data[index];
    }

    bool operator!=(const const_iterator &other) const {
        return data[index] != other.data[index] ;
    }


private:

    friend class stack; 

    const_iterator(unsigned int ind) :
        index(ind){}

}; // class const_iterator

const_iterator begin() const {
    cout << "begin" << _stack[_size-1] << endl;
    return const_iterator(_stack[_size-1]);
}

const_iterator end() const {
    cout << "end" << _stack[0] << endl;
    return const_iterator(_stack[0]);
}

И последнее, но не менее важное: я переопределил оператор << для соответствия итератору: </p>

template <typename T>
std::ostream &operator<<(std::ostream &os, const stack<T> &st) {
typename stack<T>::const_iterator i, ie;
for(i = st.begin(), ie = st.end(); i!=ie; ++i){
    os << *i << std::endl;
}
return os;
}

Код для стека следующий (что-то опущено для удобства чтения).

stack()
    : _capacity(0), _size(0), _stack(0){}
void push (const T &value){
    if (_size == _capacity){    //raddoppio la dimensione 
        if(_capacity == 0)
            ++_capacity;
        _capacity *= 2;
        T* tmp = new T[_capacity];
        copy_n(_stack, _size, tmp);
        swap(_stack, tmp);
        delete[] tmp;
    }
    _stack[_size] = value;
    ++_size;
}

void pop(){
    T _tmp;
    if(!is_empty()){
        _tmp = _stack[_size-1];
        --_size;
    }
} 

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Я следовал предыдущим советам и вот отредактированный результат, но я все еще не могу понять, как правильно использовать конструктор в приватном разделе

class const_iterator {
    const T *data;
public:
    /* ITERATOR TRAITS HERE */

    const_iterator() : data(0){}

    const_iterator(const T* arr) : data(arr) {}

    const_iterator(const const_iterator &other) 
        : data(other.data){ }

    const_iterator& operator=(const const_iterator &other) {
        data = other.data;
        return *this;
    }

    ~const_iterator() {
        data = 0;
    }

    reference operator*() const {
        return *data;
    }

    pointer operator->() const {
        return &(data);
    }

    const_iterator operator++(int) {
        const_iterator tmp(*this);
        ++*this;
        return tmp;
    }

    const_iterator& operator++() {
        ++data;
        return *this;
    }

    bool operator==(const const_iterator &other) const {
        return data == other.data;
    }

    bool operator!=(const const_iterator &other) const {
        return data != other.data;
    }

private:
    friend class stack; 

    const_iterator(const T *d) {
        data = d;
    }

}; // classe const_iterator

const_iterator begin() const {
    return const_iterator(_stack[_size-1]);
}

const_iterator end() const {
    return const_iterator(_stack[0]);
}
0 голосов
/ 06 сентября 2018

Если вы хотите создать итератор, который выглядит как указатель, вам не нужно index, потому что data играет свою роль. Оператор сравнения должен сравнивать data с, а не значения:

bool operator==(const const_iterator &other) const {
    return data == other.data;
}

Если вы хотите создать обратный итератор , он немного сложнее. Во-первых, operator++ должно уменьшаться data. Во-вторых, оператор разыменования должен возвращать не *data, а *(data - 1). В-третьих, data в итераторе begin() должен указывать на stack[size], а data в итераторе end() должен указывать на stack[0]. В любом случае вам не нужен деструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...