Понимание перегрузки оператора и итератора, почему он выводит «wrhrwwr»? - PullRequest
1 голос
/ 25 января 2020

В следующем коде вывод «wrhrwwr», я пытаюсь понять, что делает итератор, а также как перегружается «++». Кажется, это как-то пропускает «е». Тем не менее, код очень неясен для меня, может быть, мне можно помочь. Спасибо

#include <iostream> 

using namespace std;

class datas {
private: 
    const char *string,marker;
    const int len;
public:
    class hophop {
    private:
        const char *pos, next;
    public: 
        char operator *() { return *pos; }
        hophop operator ++() {++pos;while (*(pos+1)!=next)  ++pos; return *this; }
        bool operator !=(hophop &o) { return pos < o.pos; }
        hophop(const char *p, char m) : pos(p),next(m) {}
    };
    typedef hophop iterator;
    iterator begin() { return hophop (string, marker); }
    itrator end () { return hophop(string +len ,marker); }
    datas(const char *d,int l, char m) : string (d), len(l),marker(m){}
};

int main( void ) {

    datas chars ("we are where we were", 20, 'e');
    for (char c: chars)
        cout << c;

    return 0;
}

1 Ответ

1 голос
/ 25 января 2020

Это будет легче увидеть, потянув hophop из класса datas. Теперь вы можете увидеть конструктор hophop и его задачи. Я бы удалил возвращаемое значение ++operator, установил бы его void, чтобы указать, что здесь он ничего не делает.

#include <iostream> 
class hophop {
private:
    const char* pos, next;
public:
    hophop(const char* p, char m) : pos(p), next(m) {}

    char operator *() { return *pos; }
    hophop operator ++() {
        ++pos;
        while (*(pos + 1) != next)
            ++pos;
        return *this;
    }
    bool operator !=(const hophop& o) { return pos < o.pos; }
};

class datas {
private:
    using iterator = hophop;
    const char* string, marker;
    const int len;

public:
    datas(const char* d, int l, char m) : string(d), len(l), marker(m) {}

    iterator begin() { return hophop(string, marker); }
    iterator end() { return hophop(string + len, marker); }
};

int main(void) {

    datas chars("we are where we were", 20, 'e');
    //           w   r   h r  w  w r
    for (char c : chars)
        std::cout << c;

    std::cout << "\nusing a non range based for loop:"  << std::endl;

    for (hophop it = chars.begin(); it != chars.end(); ++it)
        std::cout << *it;

    std::cout << "\nor where the return value could be used:" << std::endl;
    auto it = chars.begin();
    std::cout << *it;
    for (; it != chars.end();)
        std::cout << *++it;
}

Так что теперь может быть проще увидеть, как работает оператор hophop ++ за работой. operator *() вызывается в начале l oop, поэтому независимо от того, какой первый символ, его извлекают. Затем вызывается ++operator, и он перемещает итератор как минимум один раз вперед и до тех пор, пока он не совпадет с next. Затем он возвращает символ перед матчем. Посмотрите на комментарий в основном. Возвращается первый и каждый символ перед e.

Если вы не часто используете отладчик, вам следует это сделать. поместив точку останова в operator++, вы сможете увидеть, что происходит.

ОБНОВЛЕНИЕ

Ранее я установил значение возврата ++operator в void. Как указывает @JaMiT, для оператора целесообразно возвращать *this. Я также добавил еще два цикла, они должны быть понятнее, чем использование диапазона на основе l oop. Третий пример на самом деле использует возвращаемое значение ++operator, первые два цикла - нет.

И привычка не using namespace std; Это спасет вас от неприятностей в будущем.

...