Skocz do zawartości

Problem Z Linkowaniem


Burnn

Rekomendowane odpowiedzi

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 smile.gif.

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

  • 4 weeks later...

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 smile.gif

 

Odnośnik do komentarza
Udostępnij na innych stronach

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 smile.gif

Odnośnik do komentarza
Udostępnij na innych stronach

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 blink.gif

Odnośnik do komentarza
Udostępnij na innych stronach

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

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ę
×
×
  • Dodaj nową pozycję...