DEV Community

Cover image for Dia 10 - Generics
Matheus Gomes
Matheus Gomes

Posted on

Dia 10 - Generics

Para fazer com que os nós tenham valores genéricos na minha fila circular duplamente encadeada, fiz uso de templates(generics).

O que são generics?

Generics é uma característica de algumas linguagens de programação que permitem que você escreva código que pode operar com diferentes tipos de dados sem a necessidade de duplicar o código para cada tipo. Permitindo que algoritmos sejam definidos de forma independente de tipos específicos.

Meu código então, ficou assim:

.h

#ifndef CIRCULAR_DOUBLY_LINKED_LIST_H
#define CIRCULAR_DOUBLY_LINKED_LIST_H

#include <iostream>

template <typename T>
struct Node {
    T value;
    Node* next;
    Node* prev;
};

template <typename T>
class CircularDoublyLinkedList {
public:
    CircularDoublyLinkedList();
    void Enqueue(T value);
    T Dequeue();
    void Display();

private:
    Node<T>* head;
    Node<T>* tail; 
    int size;
};

template <typename T>
CircularDoublyLinkedList<T>::CircularDoublyLinkedList() : head(nullptr), tail(nullptr), size(0) {}

template <typename T>
void CircularDoublyLinkedList<T>::Enqueue(T value) {
    Node<T>* newNode = new Node<T>{ value, nullptr, nullptr };

    if (size == 0) {
        head = newNode;
        tail = newNode;
        newNode->next = newNode;
        newNode->prev = newNode;
    }
    else {
        newNode->prev = tail;
        newNode->next = head;
        tail->next = newNode;
        head->prev = newNode;
        tail = newNode;
    }
    size++;
}

template <typename T>
T CircularDoublyLinkedList<T>::Dequeue() {
    if (size == 0) {
        std::cout << "A fila está vazia\n";
        return T();
    }

    T value = head->value;
    Node<T>* removedValue = head;

    if (size == 1) {
        head = nullptr;
        tail = nullptr;
    }
    else {
        head = head->next;
        head->prev = tail;
        tail->next = head;
    }
    size--;

    delete removedValue;
    return value;
}

template <typename T>
void CircularDoublyLinkedList<T>::Display() {
    if (size == 0) {
        std::cout << "A fila está vazia\n";
        return;
    }
    Node<T>* current = head;
    for (int i = 0; i < size; i++) {
        std::cout << current->value << " ";
        current = current->next;
    }
    std::cout << std::endl;
}

#endif

Enter fullscreen mode Exit fullscreen mode

Então, no main.cpp, a instanciação da classe fica assim:

#include <iostream>
#include "CircularDoublyLinkedList.h"

int main() {
    CircularDoublyLinkedList<int> list;

    list.Enqueue(10);
    list.Enqueue(20);
    list.Enqueue(30);

    std::cout << "Valores ";
    list.Display();

    int removedValue = list.Dequeue();
    std::cout << "Removido: " << removedValue << std::endl;

    std::cout << "Valores após Dequeue: ";
    list.Display();

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Repare que o tipo de dados que serão inseridos na fila, só foi definido na instanciação da classe CircularDoublyLinkedList.

Para os próximos passos tem coisas no meu radar:
. Quero transformar essa aplicação em uma biblioteca, e instalar ela no meu projeto real de sistema operacional
. Quero criar testes com gtest
. Quero criar um Cmake

Top comments (0)