【问题标题】:Understanding operator overloading & iterator why does it print out "wrhrwwr"?理解运算符重载和迭代器为什么会打印出“wrhrwwr”?
【发布时间】:2020-05-11 07:03:42
【问题描述】:

在下面的代码中,输出是“wrhrwwr”,我试图理解迭代器在做什么,以及“++”是如何被重载的。似乎它以某种方式跳过了“e”。但是,代码对我来说非常不清楚,也许我可以得到帮助。 谢谢

#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;
}

【问题讨论】:

    标签: c++ pointers iterator operator-overloading


    【解决方案1】:

    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 *() 在循环开始时被调用,所以无论第一个字符是什么,它都会被检索到。然后调用++operator 并将迭代器至少向前移动一次,直到它匹配next。然后它返回匹配前的字符。看看main里的评论。返回e 之前的第一个字符和每个字符。

    如果您没有经常使用调试器,那么您应该这样做。通过在operator++ 中设置一个断点,您可以看到发生了什么。

    更新

    我之前已将 ++operator 的返回值设置为 void。正如@JaMiT 指出的那样,运营商返回*this 是合适的。我还添加了两个循环,它们应该比使用基于范围的循环更清晰。第三个例子实际上使用了++operator的返回值,前两个循环没有。

    而且,养成不using namespace std; 的习惯,它会让你免于以后的麻烦。

    【讨论】:

    • 谢谢!,这对我帮助很大。所以 ++ 运算符在我的代码中没有返回任何有用的东西?
    • 不客气。是的,main 中的 for 循环只是调用 ++operator 来移动迭代器。它不寻找或做任何事情,返回值。
    • It is idiomatic for operator++() to return *this。在与仍在学习约定的人打交道时,更改代码以偏离此约定可能不是一个好主意。尤其是当这样做几乎没有收获(单行更简单)时。 (我承认在多行中打破该功能是一种好方法。)
    猜你喜欢
    • 2011-10-18
    • 1970-01-01
    • 2013-09-07
    • 2016-02-03
    • 2020-06-14
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多