Jak poprawnie zrobić szablon kolejki, żeby obsługiwał również wskaźniki?

0

mam taką klase

template <typename T>
class queueTp
{
    static const int MAX_QUEUE = 10;
    private:
        struct node { T item; node * next; };
        node * m_front, * m_rear;
        int m_rozmiar;
        const int m_max_rozmiar;
    public:
        queueTp();
        queueTp(int max_size);
        
        bool isempty(void) const;
        bool isfull(void) const;        
        bool add(T x);
        bool remove_first(void);
        
        void show(void);
};

i funkcja add

template <typename T>
bool queueTp<T>::add(T x)
{
    if( isfull() )
        return false;
        
    node * dodaj = new node;
    if(dodaj == NULL)
        return false;
        
    dodaj->item = x;
    dodaj->next = NULL;
    m_rozmiar++;
    
    if(m_front == NULL)
    {
        m_front = dodaj;
        m_rear  = dodaj;
    }
    else
        m_rear->next = dodaj;
    
    m_rear = dodaj;
    m_rear->next = NULL;
    
    return true;    
}

i chciałbym żeby ta klasa mogła być również kolejką wskaźników na dowolny typ np. queueTp<int *>
ale moja funkcja operuje wartościami, a w przypadku wskaźników będą potrzebne adresy
muszę robić osobny szablon dla wskaźników?? czt da się zrobic wszystko w jednym??

1

A dlaczego obecny kod nie nadaje się na obsługę wskaźników? Jeśli mam kontener i chcę w nim przechowywać T* to nie życzę sobie, aby kontener decydował o wykonaniu głębokiej kopii (a co jeśli T jest niekopiowalne?).

Ponadto:

    node * dodaj = new node;
    if(dodaj == NULL)
        return false;

dodaj nigdy nie będzie miał wartości NULL (przy okazji, w C++ preferowane jest użycie nullptr)

    if(m_front == NULL)
    {
        m_front = dodaj;
        m_rear  = dodaj;
    }
    else
        m_rear->next = dodaj;
 
    m_rear = dodaj;

Niepotrzebne dwukrotne przypisanie m_rear. Dobrą regułą jest, by dawać klamry w else, jeśli w ifie były zastosowane.

0

a więc tak, ja myślałem, nad czymś takim

int x = 12;
queueTp<int *> zm1;
zm1.add(x); // to niezadziała
zm1.add(&x); // zadziała

ale chciałem zrobić coś takiego że w programie mam jedna zmienną np. temp która przyjmuje jakieś wartości
i przekazujemy je do kolejki, i tak w kółko. zm1.add(temp);
i jak mam teraz

dodaj->item = x; 

będe musiał wywołać operator new
ale nie moge zrobić

dodaj->item = new T;

bo T jest teraz int* a tu jest potrzebne sam int

chyba że się robi tak że wysyłamy adresy zm1.add(&x); a ja za bardzo kombinuje

bo teraz to muszę mieć gdzieś poza klasą ten zmienne do których kolejka ma adresy. a ja chce żeby te zmienne istniały tylko w kolejce i po jej opuszczeniu znikały

1
Kosimazaki123 napisał(a):

T jest teraz int* a tu jest potrzebne sam int

Zbyt kombinujesz. Jeśli masz kontener (kolejkę) int*, to trzymaj tam tylko int*, nie próbuj trzymać innych typów. To nie ma sensu.

0

ale jak napisze sobie tak

    queueTp<int *> zm1;
    
    int temp; 
    for(int i = 0; i < 5; i++)
    {
        temp = i;
        zm1.add(&temp);
    }

jak jest samo temp w add to pisze że ivalid ..... do *int

muszę zrobić w add alokacje na nowe elementy, albo wszystkie będą wskazywać w to samo miejsce bo adres temp się nie zmienia.
i mesze zrobic coś takiego
int* x = new int;
a jak mam T x = new i tutaj co?? kiedy T jest int*

0

No ale to jest poprawne zachowanie. Dodany element jest wskaźnikiem. Nie jest rolą kontenera interpretować jego zawartości...

0

ok chyba rozumiem, w przypadku int będę przekazywał wartość ale w przypadku int* tylko adresy.

ale powiedz mi jeszcze jedno, dlaczego new nie zwraca NULL, w książce przewalają mi się takie przykłady że jeśli new nie za alokuje pamięci to zwraca NULL.
i skoro nie zwraca NULL to jak sprawdzić czy za alokował.

1

W takim razie wymień książkę na taką z tego tysiąclecia. Z tego dziesięciolecia najlepiej, ale z poprzedniego od biedy ujdzie.

new rzuca std::bad_alloc jeśli nie może zaalokować pamięci (chyba, że używasz std::nothrow)

0

mam książkę z 2006r, ale chyba lepiej będzie jeżeli znajdę jakiś opis do c++11, żeby zobaczyć co się zmieniło

0

No to jest dziwne, bo od pierwszego oficjalnego standardu C++98 new zachowuje się w ten sposób.

1 użytkowników online, w tym zalogowanych: 0, gości: 1