Burnn Napisano Grudzień 27, 2005 Zgłoszenie Share Napisano Grudzień 27, 2005 Witam Mam nastepujacy problem z prosta lista w c++ skladajaca sie z trzech plikow (main.cpp, lista.cpp i jednego headera lista.h), a mianowicie - pliki po skompilowaniu nie chca sie linkowac. Calosc (po: g++ main.o lista.o -o pr) konczy sie nastepujacym komunikatem: main.o(.text+0x45): In function `main': : undefined reference to `lista<int>::append(int const&)' main.o(.text+0x5e): In function `main': : undefined reference to `lista<int>::get_num()' main.o(.text+0x7f): In function `main': : undefined reference to `lista<int>::get(int*&)' main.o(.text+0xa7): In function `main': : undefined reference to `lista<int>::next()' main.o(.text+0xbc): In function `main': : undefined reference to `lista<int>::~lista()' main.o(.text+0xda): In function `main': : undefined reference to `lista<int>::~lista()' collect2: ld returned 1 exit status dolacze jeszce zawartosc plikow: lista.h: #define NULL 0 #define false 0 #define true 1 #ifndef LISTA #define LISTA template <class T> class elem { T &pole; elem <T> *next; elem <T> *prev; public: elem(T &ob) : pole(ob), next(NULL), prev(NULL){};//dla pierwszego elem(T &ob, elem <T> *before); elem(T &ob, elem <T> *after, int); ~elem(); void bloodlust(); //kasuj wszystkich na lewo na prawo na koncu siebie elem <T> *get_next(); elem <T> *get_prev(); T & get_pole(); }; template <class T> class lista { elem <T> *current; elem <T> *beg; elem <T> *end; int num; public: lista() : current(NULL), beg(NULL), end(NULL), num(0){}; ~lista(); int append(const T & ob); int insert(const T & ob, int nr); bool remove(int number); bool next(); bool prev(); void endd(); void begin(); int get_num(); bool get(T *&buf); }; lista.cpp #include "lista.h" template <class T> lista <T> :: ~lista() { if (beg) beg -> killspree(); delete beg; } /***************************************************************************/ template <class T> int lista <T> :: append(const T & ob) { elem <T> *nowy; T *newobj = new T; *newobj = ob; if (!num) { nowy = new elem <T> (*newobj); beg = end = current = nowy; } else nowy = new elem <T> (*newobj, end, 1); if (!nowy) return 1; //brak pamieci num++; return 0; } /***************************************************************************/ template <class T> int lista <T> :: insert(const T & ob, int nr) { int n = 1; elem <T> *nowy; T *newobj = new T; *newobj = ob; if (!num) return append(*newobj); for (elem <T> *wsk = beg; wsk; wsk = wsk -> get_next, n++) if (n == nr) { nowy = new elem <T> (newobj, wsk); if (!nowy) return 1; //blad: brak pamieci num ++; return 0; //ok } return 2; //blad: nie znaleziono } /***************************************************************************/ template <class T> bool lista <T> :: remove(int number) { int n = 1; if (number > num) return 1; //nie znaleziono for (elem <T> *wsk = beg; wsk; wsk = wsk -> get_next, n++) if (n == number) { delete wsk; num--; return 0; //ok } return 1; //nie znaleziono } /***************************************************************************/ template <class T> bool lista <T> :: next() { if (current) current = current -> get_next(); if (!current) return false; return true; } /***************************************************************************/ template <class T> bool lista <T> :: prev() { elem <T> *n; if (current) n = current -> get_prev(); else return false; if (n) current = n; else return false; //niepowodzenie return true; //ok } /***************************************************************************/ template <class T> void lista <T> :: endd() { current = end; } /***************************************************************************/ template <class T> void lista <T> :: begin() { current = beg; } /***************************************************************************/ template <class T> int lista <T> :: get_num() { return num; } /***************************************************************************/ template <class T> bool lista <T> :: get(T *&buf) { if (current) buf = &(current -> get_pole()); else return (buf = false); return true; } /***************************************************************************/ ///////////////////////////////////////////////////////////////////////////// template <class T> elem <T> :: elem(T &ob, elem <T> *before) : pole(ob) { elem <T> *save = before -> prev; before -> prev = this; prev = save; next = before; if (save) save -> next = this; } /**************************************************************************/ template <class T> elem <T> :: elem(T &ob, elem <T> *after, int) : pole(ob) { elem <T> *save = after -> next; after -> next = this; prev = after; next = save; if (save) save -> prev = this; } /**************************************************************************/ template <class T> elem <T> :: ~elem() { if (next) next -> prev = prev; if (prev) prev -> next = next; } /**************************************************************************/ template <class T> void elem <T> :: bloodlust() { while (next) delete next; while (prev) delete prev; } /**************************************************************************/ template <class T> elem <T>* elem <T> :: get_next() { return next; } /**************************************************************************/ template <class T> elem <T>* elem <T> :: get_prev() { return prev; } /**************************************************************************/ template <class T> T & elem <T> :: get_pole() { return pole; } main.cpp #include <stdio.h> #include "lista.h" int main() { lista <int> List; int *buf; for (int i = 1; i < 10; i++) List.append(i); printf("ilosc elementow dodanych:%d\n\n", List.get_num()); do { if (List.get(buf)) printf("%d\n", *buf); } while (List.next()); return 0; } Z gory dzieki za wszelka pomoc . Ok juz mniej wiecej wiem o co chodzi, a dokladniej o wielokrotne instancje klas szablonowych w kazdym z plikow w ktorym zostaly uzyte. Sprawe zalatwilem dolaczajac pliki w ktorych pojawiaja sie takowe do main.c(#include) . Jezeli ktos ma lepszy sposob prosze dac znac. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Styczeń 18, 2006 Zgłoszenie Share Napisano Styczeń 18, 2006 Na początek zrób sobie małe poprawki: w pliku lista.h zamiast #define NULL 0 wpisz #ifndef NULL #define NULL 0 #endif oraz w pliku lista.cpp zamiast beg -> killspree(); wpisz beg -> bloodlust(); Tyle odnośnie źródeł. Co do wyniku kompilacji to u mnie jest to samo i nie wiem dlaczego. Być może brakuje dołączonej jakiejś opcji albo coś... W każdym razie jak przeniesiesz kod z pliku main.cpp do pliku lista.cpp i skompilujesz, to wszystko śmiga pięknie Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
neo_fox Napisano Styczeń 18, 2006 Zgłoszenie Share Napisano Styczeń 18, 2006 A pliki obiektowe jak tworzyłeś? Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Styczeń 19, 2006 Zgłoszenie Share Napisano Styczeń 19, 2006 A pliki obiektowe jak tworzyłeś? Najpierw tak: g++ -Wp,-D_FORTIFY_SOURCE=2 -Wall -c lista.cpp -o lista.o g++ -Wp,-D_FORTIFY_SOURCE=2 -Wall -c main.cpp -o main.o g++ main.o lista.o -o main a później tak: g++ -Wp,-D_FORTIFY_SOURCE=2 -Wall -o main main.cpp lista.cpp i za każdym razem to samo. To coś przez te template'y. Częściowo sprawę rozwiązuje dodanie linijki: #include "lista.cpp" do pliku main.cpp (jako pewna wariacja umieszczenia wszystkiego w jednym pliku). Jeśli jednak wiesz jakich opcji użyć, żeby się to skompilowało bez inkludowania lista.cpp, to będę wdzięczny za podpowiedź, gdyż samego mnie to zainteresowało Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
neo_fox Napisano Styczeń 19, 2006 Zgłoszenie Share Napisano Styczeń 19, 2006 Teraz to już zupełnie zgłupiałem. Spróbowałem właścnie skopilować prosty program przy pomocy gcc *.c -o test i wywala mi dokładnie takie same błędy jak Wam. A jestem na 100% pewien że wcześnie tak już robiłem i działało Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Styczeń 20, 2006 Zgłoszenie Share Napisano Styczeń 20, 2006 i wywala mi dokładnie takie same błędy jak Wam. A jestem na 100% pewien że wcześnie tak już robiłem i działało Może to jakieś specjalne rozszerzenia najnowszego kompilatora a wcześniej używałeś starszej wersji... Ja własnych klas szablonowych dawno już nie tworzyłem i ciężko mi tutaj coś więcej doradzić. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się