Итератор дает разные результаты в зависимости от использования C ++ - PullRequest
0 голосов
/ 22 декабря 2018

Я недавно начал программировать на С ++.Я перешел с Java.Я строил свой собственный шаблон класса Iterable следующим образом:

template<class T> class Iterable
    {
        T start,stop;
    public:
        explicit Iterable(T s,T e) {start=s; stop=e;;}


    public:
        virtual void next(T& i) =0;
    public:
        class iterator: public std::iterator<
        std::input_iterator_tag,   // iterator_category
        T,                      // value_type
        long,                      // difference_type
        const T*,               // pointer
        T                       // reference
        >{
            T current;
            Iterable<T>* obj;
        public:
            explicit iterator(T t,Iterable<T>* o) : obj(o) {current=t;}
            iterator& operator++() {obj->next(current); return *this;}
            iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
            bool operator==(iterator other) const {return current == other.current;}
            bool operator!=(iterator other) const {return !(*this == other);}
            const T& operator*() const {return current;}
        };
        iterator begin() {return iterator(start,this);}
        iterator end() {return iterator(stop,this);}
    };

Когда я пытался использовать этот итератор, я получал разные результаты, когда вызывался по-разному:

for(auto S=SI.begin();S!=SI.end();S++)
    {
        cout << *S << "\n";
        //cout << contains(seqs,S) << "\n";
        if(!contains(seqs,*S))
            seqs.push_back(*(new Sequence(*S)));
    }

давал разные результаты из:

for(Sequence S : SI)
    {
        cout << S << "\n";
        //cout << contains(seqs,S) << "\n";
        if(!contains(seqs,S))
            seqs.push_back(*(new Sequence(S)));
    }

даже в цикле.Мой класс SeqIter (SI является объектом этого класса) выглядит следующим образом:

class SeqIter : public flex::Iterable<Sequence>
{
    int n;
public:
    SeqIter(int s) : Iterable(Sequence(copyList(0,s),s),Sequence(copyList(3,s),s)) {n=s;}

    void next(Sequence& s)
    {
        char ch;
        for(int i=0;i<n;i++)
        {
            ch=nextBase(s[i]);
            s[i]=ch;
            if(ch!=0)
                break;
        }
    }
};

Извините, если это слишком много кода, но я не знаю, сколько кода требуется.


Кроме того, краткое объяснение класса Sequence: это класс, имеющий массив чисел (в данном случае я пробовал с 3), и он генерирует следующие последовательности на основе первой, то есть 000, 100, 200, 300;010,110 ... Каждая цифра колеблется от 0 до 3 (включая оба). Я не могу понять, почему оба цикла дают разные последовательности (первый дает 000 100 200 300 010 110, а второй дает 000 100 200 300 000 110) Я думал, что оба цикла были в основном одинаковыми, и что первый был просто расширением второго.Разве это не так?

Также класс последовательности: (Извините за задержку, но я думаю, что это проблема)

class Sequence
{
    int size=1;
    char* bps;
public:
    Sequence() {size=0;}
    Sequence(int s) 
    {
        size=s;
        bps=new char[s];
    }
    Sequence(char* arr,int s)
    {
        size=s;
        bps=arr;
    }
    Sequence(const Sequence& seq)
    {
        size=seq.size;
        bps=new char[size];
        strcpy(bps,seq.bps);
    }

    String toString() const {return *(new String(bps,size));}
    inline char* toCharArray() {return bps;}
    inline int getSize() const {return size;}

    //operator overloading
public:
    bool operator==(const Sequence& s2) const
    {
        if(s2.size!=size)
            return false;
        String r1=toString();
        String r2=s2.toString();
        return (r1==r2 || r1==r2.reverse());
    }
    inline bool operator!=(const Sequence& s2) const {return !operator==(s2);}
    const char& operator[](int n) const
    {
        if(n>=size)
            throw commons::IndexOutOfBoundsException(n,size);
        return bps[n];
    }
    char& operator[](int n)
    {
        if(n>=size)
            throw commons::IndexOutOfBoundsException(n,size);
        return bps[n];
    }
    Sequence& operator=(const Sequence& seq)
    {
        size=seq.size;
        bps=new char[size];
        strcpy(bps,seq.bps);
    }
};

1 Ответ

0 голосов
/ 23 декабря 2018

Извините всех.Отвечая на мой собственный вопрос после отладки: в своем классе Sequence я использовал strcpy при копировании char *, где массив не заканчивался символом '\ 0'. Возможно, это вызвало ошибку: я прочитал в Интернете немного больше, чтобы обнаружить, что расширениебыло следующим образом:

for(Sequence S : seqs)
{
...
}

эквивалентно

for(auto i=SI.begin();i!=SI.end();i++)
{
Sequence S=*i;
...
}

Таким образом, в назначении (S = * i) данные не были должным образом скопированы.Извините за все проблемы

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

Sequence(const Sequence& seq)
{
        size=seq.size;
        bps=new char[size];
        for(int i=0;i<size;i++)
            bps[i]=seq[i];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...