Własna implementacja listy - gdzie tu jest błąd?

0

Witam, chcę zaimplementować własną listę, gdzie ja tutaj mam błąd, że podany niżej kod nie działa. Chodzi głównie o to, że np. jak mam w konstruktorze "first->..." to IDE nie wykrywa składników first, czyli "next" i "value". Gdy zamieniam klasę z szablonu na normalną, jest ok, ale gdy jest szablonem, to jest powyższy problem.


#include <iostream>
using namespace std;

template <typename value_type>
class List
{
private:
    // typy
    struct Node {int value; struct Node * next;};
public:
    // konstruktory, destruktor
    List(int n=0);
    // metody publiczne
    void print();
private:
    // atrybuty
    int size;
    Node * first;
    struct Node * last;
};

template <typename value_type>
List<value_type>::List(int n=0)
{
    first=NULL;
    last=NULL;

    if (n>0)
    {
        first=new Node;
        **first->next=NULL;**
        last=first;
        for (int i=0;i<n;++i)
        {
            last->next=new Node;
            last=last->next;
        }
    }
}

template <typename value_type>
void List<value_type>::print()
{
    Node * temp=first;
    while (temp!=NULL)
    {
        cout<<temp->value<<" ";
        temp=temp->next;
    }
}

Z góry wielkie dzięki za pomoc! :)

0
matieti napisał(a):

IDE nie wykrywa składników first
Hmm... niech zgadnę, Dev-Cpp?

0

Visual Studio 2010 :P

0

A co, wam wyskakują te propozycje składników?

0

Ale to masz problem z programem, że coś nie działa, czy z tym, że środowisko nie wyświetla podpowiedzi?

0

Nie no wydaje mi się, że problem jest gdzieś w składni mojego "programu" :P

0

Jeżeli używasz VS2010 i C++, to problem może leżeć po stronie środowiska. Bo ja Twój kod skopiowałem i się ładnie kompiluje (wysypuje się w print() podczas działania, ale to zaraz popatrzę co jest nie tak). Natomiast to że środowisko nie pokazuje podpowiedzi (u mnie również) nie oznacza, że coś skopałeś (tym bardziej że się kompiluje). A w tym wypadku jest trochę winą Microsoftu, bo właśnie w VS2010 odpuścili sobie IntelliSense w C++ i są problemy w niektórych momentach z pokazywaniem co jaka klasa zawiera. To sam MS się przyznał do błędu, więc to nie wina kodu.

0

teraz już niestety przy funkcji "operator[]" wyskakuje błąd kompilacji, wiecie może co jest nie tak?


#include <iostream>
using namespace std;

template <typename value_type>
class List
{
public:
    // typy
    struct Node {int value; struct Node * next;};
    // konstruktory, destruktor
    List(int n=0);
    // metody publiczne
    void print();
    Node * operator[](int n);
private:
    // atrybuty
    int size;
    Node * first;
    struct Node * last;
};

template <typename value_type>
List<value_type>::List(int n=0)
{
    first=NULL;
    last=NULL;

    if (n>0)
    {
        first=new Node;
        first->next=NULL;
        last=first;
        for (int i=0;i<n;++i)
        {
            last->next=new Node;
            last=last->next;
        }
    }
}

template <typename value_type>
void List<value_type>::print()
{
    Node * temp=first;
    while (temp!=NULL)
    {
        cout<<temp->value<<" ";
        temp=temp->next;
    }
}

template <typename value_type>
List<value_type>::Node * List<value_type>::operator[](int n)
{
    Node * temp=first;
    for (int i=1;i<n;++i)
        temp=temp->next;
    return temp;
}
0

Błąd wysypywania się przy print jest spowodowany tym, że jeżeli do konstruktora przekażesz n > 0 to ostatni element nie będzie miał ustawionego pola next na NULL, tylko na jakieś śmieci. Musi dać last->next = NULL; zaraz za tą pętlą tworzącą elementy.

Co do podpowiadania składni to się nie przejmuj. Intelisense nie zawsze sobie radzi z szablonami, przynajmniej jak jeszcze nie istnieje żadna ich konkretyzacja(chociaż to nie do końca tak jest).

@Lena(R): MS odpuścił sobie intelisense nie tyle w c++ co w c++/cli

0

No to masz klasyczny błąd przy tworzeniu nowych elementów w liście. Tu nie chodzi o print(), ale o konstruktor i pętle. Mój konstruktor wygląda tak:

template <typename value_type>
List<value_type>::List(int n=0)
{
        first=NULL;
        last=NULL;

        if (n>0)
        {
                first=new Node;
                first->next=NULL;
                last=first;
                for (int i=1;i<n;++i)   // i=0  =>  i=1 , nie ma sensu gdy i==0, bo wtedy tworzy pierwszy (zerowy) element listy, a to zrobiłeś powyżej. Więc jeżeli n > 1, to petla się obróci i doda nowe elementy, w przeciwnym wypadku jest to niepotrzebne.
                {
                    last->next=new Node;
                    last->next->next = NULL;    // nigdzie nie NULLowałeś nexta nowo utworzonego elementu, przez co warunek w print nigdy sie nie zakonczyl i program sie wysypywal bo probowal dostac sie do nie zainicjalizowanej pamieci.
                    last=last->next;
                }
        }
}

Chodziło o nullowanie elementu, aby zapewnić sobie koniec listy.

Rozumiem że ten kod, to jest taki test. Bo jak na razie, nie mozesz ani wstawiać, ani usuwać nic. Nie zwalniasz też pamięci w destruktorze (którego w ogóle tutaj nie masz).

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