Как создать функцию для адресации узла двусвязного списка?

#c #class #oop #templates #doubly-linked-list

#c #класс #ооп #шаблоны #двусвязный список

Вопрос:

Я реализовал двусвязный список как класс в C

В main.cpp Я помещаю объекты другого класса в этот список следующим образом

 list.insertBack(ClassA(name, description));
  

Но после этого мне нужно изменить определенное поле этого объекта, например, выполнить метод, который изменяет население. Для этого мне нужно каким-то образом адресовать этот объект из списка, как я бы поступил с обычным массивом (что-то вроде a[i] ). Для этого мне нужен специальный метод / функция в моем классе List. Как я могу это реализовать?

Комментарии:

1. Конечно, вы можете реализовать operator[] для своего класса List . Будет ли он использоваться find под капотом? Если да, то что вы будете делать в случае, find когда возвращается nullptr ?

Ответ №1:

Вам просто нужно предоставить a operator[] для вашего класса:

 template<class T>
class List {

    // your private interface

public:

    // your other public interface 

    Tamp; operator[](unsigned int i)
    {
        Node* n = this->head;
        for (; i>0; --i)
        {
            n = n->next;
        }
        return n->data;
    }
};
  

В вашем основном вы можете просто использовать его как

 int main() {
    List<double> l;
    l.insertBack(0.0);
    l.insertBack(1.0);
    l.insertBack(2.0);
    l.insertBack(3.0);

    std::cout <<  l[2] << std::endl;
}
  

Обратите внимание, что вам также может понадобиться const версия этой функции. Вот демонстрация.

Примечание: Как указано @Botje, вы также можете захотеть выполнить некоторые проверки работоспособности входных данных. Если i равно или больше числа существующих узлов, мой фрагмент кода разыменовывает a nullptr , и вы получаете неопределенное поведение.

Комментарии:

1. Что произойдет, если i больше, чем количество узлов в списке?

2. @Botje Спасибо, что указали на это. Затем я разыменовываю nullptr , и это приведет к неопределенному поведению. Как и в std::vector::operator[] , я здесь не делаю никаких проверок.

3. Спасибо! Как я могу использовать это с методами из класса City? Например, я хочу сделать list[2].event() что-то вроде этого void City::event() { cout << "Special event happening in city" << this->name << endl; }

4. @kekundel Я обновил ответ. Теперь он возвращается Tamp; . В вашем случае вы получаете ссылку на City объект.