Пользовательский список с поддержкой для каждого C++

В начале я хочу извиниться за мой английский. Моя проблема странная, потому что я пытаюсь написать собственный ArrayList, который выглядит и работает как List в Java, и я знаю, что это как изобретать колесо, но я делаю это для удовольствия и для лучшего понимания, как это работает. Таким образом, каждый ответ, такой как "использовать STL", "использовать вектор", "использовать что-то другое, но не создавать собственный список", бесполезен. Итак, с самого начала у меня есть собственный шаблон для ArrayList с несколькими важными для меня методами. Мой ArrayList работает как массив, где я использую только часть доступного пространства, и если мне нужно больше места, я создаю новый больший массив и копирую все старые элементы (я считаю, что, как это работает в Java ArrayList, скажите мне, если я ошибаюсь), В массиве я храню только указатели. И это хороший шаблон для сохранения и удаления известных объектов, и если мне нужно только прочитать сохраненные данные, но реальная проблема возникает, когда я пытаюсь написать цикл для чтения, проверить и удалить указанный элемент из списка. Я не могу сделать это, используя стандарт для (Int I =0; я

Так может кто-нибудь объяснить мне, что я должен написать в своем шаблоне для поддержки каждой функции. Во многих примерах появляются функции begin() и end(), но никто не объясняет, почему это имя, что является типом возврата и почему, и что должен возвращать этот метод. Вот мой код шаблона, если что-то не так, пожалуйста, сообщите мне. Я буду использовать этот код в других своих приложениях, потому что для меня эта реализация более интуитивная, чем векторная (я определенно слишком долго работал с Java:))

template <class T> class ArrayList {

public:
    ArrayList() {
        array = new T*[1000];
        arraySize = 1000;
        n = 0;
    };

    void add(T &arg) { //add new element at end
        if (n == arraySize) {
            increase();
        }
        array[n] = &arg;
        n++;
    };

    void addAt(T &arg, unsigned int pos) { //add new element at specific position and override
        if (pos >= 0 && pos <= n) {
            if (pos == n) {
                add(arg);
            }
            else {
                array[pos] = &arg;
            }
        }
        else {
            throw "IndexOutOfBoundException";
        }
    };

    void addAfter(T &arg, unsigned int pos) { //add new element between specific posittion and next element
        pos++;
        if (pos >= 0 && pos <= n) {
            if (n == arraySize) {
                increase();
            }
            for (unsigned int i = n; i > pos; i--) {
                array[i] = array[i - 1];
            }
            array[pos] = &arg;
            n++;
        }
        else {
            throw "IndexOutOfBoundException";
        }
    };

    void addList(ArrayList &list) { //add 'list' at the end
        if (list.n > 0) {
            while (list.n + n > arraySize) {
                increase();
            }
            for (int i = 0; i < list.n; i++) {
                array[n] = list.array[i];
                n++;
            }
        }
    };

    void addListAfter(ArrayList &list, unsigned int pos) { //put 'list' inside list, start from 'pos'
        pos++;
        if (list.n > 0 && pos >= 0 && pos < n) {
            while (list.n + n > arraySize) {
                increase();
            }
            int m = n - 1;
            while (m >= pos && m >= 0) {
                array[m + list.n] = array[m];
                m--;
            }
            for (int i = 0; i < list.n; i++) {
                array[pos + i] = list.array[i];
            }
            n += list.n;
        }
        else {
            throw "IndexOutOfBoundException";
        }
    };

    void addListAfter(ArrayList &list, T &arg) { //put 'list' inside list, start after T, if T not exist 'list' will be added at the end
        addListAfter(list, getIndex(arg));
    };

    void remove(T &arg, bool all) { //remove selected element if all=true remove all instance of object otherwise remove only first
        if (all) {
            int copies = 0;
            for (int index = 0; index < n; index++) {
                if (array[index] == &arg) {
                    copies++;
                }
                else if (copies != 0) {
                    array[index - copies] = array[index];
                }
            }
            n -= copies;
            if (copies == 0) {
                throw "ArgumentNotFoundException";
            }
            while (arraySize - n >= 1000) {
                decrease();
            }
        }
        else {
            remove(getIndex(arg));
        }
    };

    void remove(unsigned int pos) { //remove element from specific position
        if (pos >= 0 && pos < n) {
            for (int i = pos; i < n - 1; i++) {
                array[i] = array[i + 1];
            }
            n--;
            if (arraySize - n >= 1000) {
                decrease();
            }
        }
        else {
            throw "IndexOutOfBoundException";
        }
    };

    void removeCopy(T &arg) { //leaves only one instance of an object and remove all other
        int copies = -1;
        for (int index = 0; index < n; index++) {
            if (array[index] == &arg) {
                copies++;
            }
            else if (copies > 0) {
                array[index - copies] = array[index];
            }
        }
        n -= copies;
        if (copies == -1) {
            n--;
            throw "ArgumentNotFoundException";
        }
        while (arraySize - n >= 1000) {
            decrease();
        }
    };

    void repair() { //leaves only single instance of each object
        for (int i = 0; i < n; i++) {
            removeCopy(*array[i]);
        }
    };

    void clear() { //remove all object from list
        for (int i = 0; i < n; i++) {
            array[i] = NULL;
        }
        n = 0;
    };

    T* get(unsigned int pos) { //return object on selected position
        if (pos >= 0 && pos < n) {
            return array[pos];
        }
        else {
            throw "IndexOutOfBoundException";
        }
    };

    unsigned int getIndex(T &arg) { //return position of selected object
        unsigned int index = 0;
        while (&arg != array[index] && index < n) {
            index++;
        }
        if (index == n) {
            throw "ArgumentNotFoundException";
        }
        return index;
    };

    ArrayList getSubList(unsigned int first, unsigned int last, bool deepCopy) { //return new list contains 'deep copy'/'copy reference' of all elements from (include) first to (include) last. If deepCopy=true function return deep copy, otherwise return copy of reference.
        if (first < last&&first >= 0 && last < n) {
            ArrayList<T> ret;
            for (unsigned int i = first; i <= last; i++) {
                if (deepCopy) {
                    ret.add(*new T(*array[i]));
                }
                else {
                    ret.add(*array[i]);
                }
            }
            return ret;
        }
        throw "IndexOutOfBoundException";
    };

    unsigned int size() { //return size of list
        return n;
    };

    bool isEmpty() {
        return n == 0;
    };

    T *begin() {
        return &*array[0];
    }
    T  *end() {
        return &*array[n];
    }

private:
    unsigned int arraySize; //actual size of array
    unsigned int n; //number of elements in array
    T** array;

    void increase() { //increase size of array about 1000
        if (arraySize + 1000 <= LONG_MAX) {
            T** newArray = new T*[arraySize + 1000];
            for (unsigned int i = 0; i < arraySize; i++) {
                newArray[i] = array[i];
            }
            delete[] array;
            array = newArray;
            arraySize += 1000;
        }
        else {
            throw "ArraySizeOutOfBoundException";
        }
    };

    void decrease() { //decrease size of array about 1000
        if (arraySize - 1000 > 0) {
            arraySize -= 1000;
            T** newArray = new T*[arraySize];
            for (unsigned int i = 0; i < arraySize; i++) {
                newArray[i] = array[i];
            }
            delete[] array;
            array = newArray;
        }
        else {
            throw "ArraySizeOutOfBoundException";
        }
    };
};

1 ответ

Решение

Некоторые ответы, которые вы опубликовали, дают хорошие объяснения. begin а также end вернуть итераторы в контейнер, с begin ссылаясь на первый элемент и end на позицию один элемент после последнего элемента. Что касается имен, они кажутся интуитивно понятными. Я считаю, что этот дизайн итератора был выбран в качестве абстракции над указателями, которые имели бы минимальные затраты времени выполнения.

Я уверен, что вы видели эту ссылку в ответах, на которые вы ссылались, но вам следует обращаться к этой странице в циклах for-based.

В любом случае, вы, кажется, смущены элементами массива против итераторов, указывающих на элементы. С:

T **begin() {
    return &array[0];
}
T  **end() {
    return &array[n];
}

Ваша программа будет работать с дистанционным. Ваш тип элемента T*не T,

Другие вопросы по тегам