C ++ не может преобразовать Student * в DYNVECTOR :: Узел * в инициализации - PullRequest
0 голосов
/ 06 августа 2020

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

Дело в том, что я продолжаю получать эту ошибку, когда пытаюсь инициализировать какой-то студенческий класс для целей тестирования на некоторых назначение для итератора, я не могу понять, почему я, имея эту ошибку, потратил на нее много часов, и невозможно понять, почему возникает эта ошибка ..

Вот код

some edit

Вот основная функция, которую я пытаюсь использовать, которая берет итератор из моего класса

some edit

Просто в начале класса DYNVECTOR в основном мой код не работает, я продолжаю получать ошибку:

ошибка: невозможно преобразовать «Студент *» в «DYNVECTOR» :: Node * 'в инициализации Iter (T * N): _pointer (N) {}

EDIT: пожалуйста, ребята, сосредоточьтесь на этой части: inputIterator begin () {return inputIterator (pa);} вот что вызывает ошибку, функциональность функции возврата pu sh и других функций все еще выполняется, но это не причина, вызывающая эту ошибку.

Ответы [ 2 ]

3 голосов
/ 06 августа 2020

Проблема

inputIterator begin() { return inputIterator(pa);}

вызывает inputIterator конструктор

Iter(T *N ) : _pointer(N) { }

с указателем на T, T *. Iter успешно принимает T *, но пытается сохранить это T * в _pointer, а _pointer определяется как

Node *_pointer;

, который НЕ является T *. Присваивание не выполняется, потому что типы не совпадают.

Простое решение

Обеспечьте соответствие типов. Это означает, что вы должны передать Node *. Плохие новости: DYNARRAY не может дать Node *. Наивное решение не работает.

Правильное решение

Выбросьте Node. Node полезно, если у вас есть связанный список. У вас нет связанного списка. Убей это. Сделай это мертвым. Убери беспорядок.

class DYNVECTOR
{
    // no nodes
    class Iter // directly uses T pointers
    {
    public:
        Iter(T *N) :
                _pointer(N) // types match now        
        {
        }
        T& operator*() const
        {
            return *_pointer; // simpler without Node, no?
        }
        T* operator->() const
        {
            return _pointer; // simple
        }
        Iter& operator++()
        {
            _pointer++; // dead simple
            return *this;
        }
        Iter operator++(int)
        {
            Iter tmp = *this; 
            _pointer++; // yawn-city
            return tmp;
        }
        bool operator==(Iter const &rhs) const
        {
            return _pointer == rhs._pointer; // unchanged
        }
        bool operator!=(Iter const &rhs) const
        {
            return _pointer != rhs._pointer; // unchanged
        }
    private:
        T *_pointer; // T *, not Node *

    };
private:
    size_t someCap, length; //, initCap; don't see the point of initCap
    T *pa; // unchanged
public:
    typedef Iter inputIterator;
    DYNVECTOR():
        someCap(Capacity), // Still not sure what Capacity is for, so I used
                           // it here instead of magic number 24
        length(0),
        pa(new T[someCap])
    {
        // used initializer list instead.
    }

    inputIterator begin()
    {
        return inputIterator(pa); // unchanged
    }
    inputIterator end()
    {
        return inputIterator(&pa[length]);  // iterator to one past the end.
                                            // just like std::vector
    }
    template<class Iter>
    DYNVECTOR(const Iter &begin, const Iter &end): // far more versatile if const references
        DYNVECTOR() // delegate basic set-up to default constructor
    {
        for (Iter pointer = begin; pointer != end; pointer++) // loop unchanged
        {
            push_back(*pointer);
        }
    }
    // make uncopyable (for now anyway) See Rule of Three 
    // linked below for why
    DYNVECTOR(const DYNVECTOR & ) = delete;
    DYNVECTOR& operator=(const DYNVECTOR & ) = delete;
    
    ~DYNVECTOR() // for my own testing. left as example
    {
        delete[] pa; // clean up allocated storage
    }
    
    void push_back(const T & newb) // for my own testing. left as example
    {
        if (length == someCap) // need more space
        {
            int newCap = someCap * 2; // double the size
            // you might need to do something different like 
            // int newCap = someCap + Capacity;
            // There's no way for me to know. 
            // The rest should be right though.
            T* newArr = new T[newCap]; // allocate bigger array
            for (size_t index = 0; index < length; index++)
            { // copy old array into new
                newArr[index] = pa[index];
            }
            delete[] pa; // discard old array
            pa = newArr; // use new array
            someCap = newCap; // update capacity
        }
        pa[length] = newb; // insert new item
        length++; // update counter
    }
};

Документация по Правилу трех и друзьям . Вы не сможете написать сложный и эффективный C ++, если не поймете эти правила. Выучите их или станьте хакером.

0 голосов
/ 06 августа 2020

Прежде всего, когда вы имеете дело с объектами, это плохая практика:

DYNVECTOR<Student, 24> students;

Это должно быть:

DYNVECTOR<Student*, 24> students;

Во-вторых, вы никогда не создавали конструктор для вашего DYNVECTOR, как вы ожидаете, что объект будет создан ??

...