Создания класса для работы со списком

386
31 января 2017, 22:01

Задание: создать класс - двухсвязный список, создать конструктор, деструктор. Методы работы с списком: добавление, удаление элементов, сортировка списка, поиск в нем.

Набросал небольшую структуру класса, с C++ практически не знаком, возможно есть более правильный способ реализации.

Будет ли верно вводить данные прямо в конструкторе? Или для этого нужно создавать приватный метод и уже его вызывать?

struct tList
{
    int key;
    tList * prev;
    tList * next;
};
    class List
    {
        private:
            tList * beginList;
            tList * endList;
        tList* getElement(void){
            //выделение памяти
            //заполнение данных в структуре
        }
        public:
            List(){
                //ввод данных в список
                //вызов addElement
            }
            void addElementEnd(){
                //вызов getElement
                //добавление элемента в конец списка
            }
            void addElementBegin(){
                //вызов getElement
                //добавление элемента в начало списка
            }
            void deleteElement(tList * element){
                // удаление элемента
            }
            void sortAsc(){
                // по возростанию
            }
            void sortDesc(){
                // по убыванию
            }
            tList* searchElement(int key){
                //поиск элемента
            }
            void printList(){
                //печать списка
            }
            ~List(){
                //освобождение памяти
            }
        };
Answer 1

Для начала лучше сделать структуру tList внутренней структурой класса List, так как она относится к деталям реализации списка.

Класс должен иметь конструктор по умолчанию, чтобы можно было создавать пустой список.

Можно также создать конструктор, который принимает список инициализации std::initializer_list<int>, и сразу же формирует список из элементов этого списка инициализации. В этом случае вы можете в теле конструктора использовать как открытую функцию addElementEnd, которая добавляет элементы в конец списка, так и отдельно написанную закрытую функцию класса, если ее написание будет оправданно ее большей эффективностью по сравнению с открытой функцией класса.

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

В стандарте C++ для стандартных контейнеров такой конструктор определен. Это конструктор, принимающий два итератора (третий параметр имеет аргумент по умолчанию). Но это шаблонный конструктор. Вот как он выглядит

template <class InputIterator> 
list(InputIterator first, InputIterator last, const Allocator& = Allocator()); 

Если вы не хотите связываться с шаблонами, то можете написать аналогичный конструктор, который принимает два указателя: на начало массива и на место после последнего элемента массива. То есть это будет выглядеть как специализация стандартного шаблонного конструктора для конкретных итераторов, имеющих тип const int *.

List( const int *first, const int *last );

или можно как вы первоначально указали

List( const int a[], size_t n );

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

Answer 2

Да конечно можно и даже нужно создавать столько конструкторов сколько предполагает сценарий использования объектов класса. Если только ваш список не несет какой-то специальной функции.

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

Еще, как оффтоп, getElement не удачное название, лучше назвать createElement или makeElement. Просто get предполагает получение доступа к уже существующему объекту.

READ ALSO
какой добавить класс (или библиотеку) для функций canvas?

какой добавить класс (или библиотеку) для функций canvas?

не дает в подсказках никаких функций для рисованияМожет нужно добавить что то в библиотеки? или обьявить где то этот класс? radstudio c++builder fmx

438
Как обработать callback из dll?

Как обработать callback из dll?

Имеется dll-библиотека, экспортирующая функцииОна может вызывать callback-функцию, указатель на которую был передан ранее как параметр одной...

364
Решение задач на Графы С++ [требует правки]

Решение задач на Графы С++ [требует правки]

Помогите пожалуйста найти понятную литературу о ГрафахМожете объяснить хотя бы один пример на практике? Как считать матрицу смежности или...

425
Подключение базы mysql в виде файла в python

Подключение базы mysql в виде файла в python

Когда работал с msSQL и делал приложение на С# была возможность подключить бд в виде файла и работать с ней не имея запущенного сервераИнтересует...

335