Strona 1 z 1

[+] C++ - kompilacja kilku plików

: 03 stycznia 2009, 21:39
autor: zygi151
Mam kilka plików do kompilacji mianowicie:
  • k1.h
    k1.cpp
    k2.h
    main.cpp
W k1.cpp znajdują się definicje 2 funkcji.
Podczas kompilowania (z pliku main.cpp wyłączam funkcje które są definiowane w k1.cpp):

Kod: Zaznacz cały

g++ main.cpp -Wall -o main.o
Proces kompilacji przebiega bez problemu.
Jednak gdy do main.cpp dopisuje funkcję (pokaz) z pliku k1.cpp, to podczas kompilacji wypisuje mi taki błąd:

Kod: Zaznacz cały

/tmp/ccOpUTWf.o: In function `main':
main.cpp :( .text+0xe1): undefined reference to `zespolona: :p okaz()'
collect2: ld returned 1 exit status
I nie bardzo rozumiem o co chodzi.

Deklaracja funkcji jest w pliku k1.h, a definicja wygląda bardzo prosto (plik k1.cpp):

Kod: Zaznacz cały

void zespolona: :p okaz()
{
 cout << rzeczyw << endl << urojon << endl;
}
Próbowałem też kompilować w ten sposób:

Kod: Zaznacz cały

g++ k1.cpp main.cpp -Wall -o main.o
ale dostawałem takie błędy:

Kod: Zaznacz cały

k1.cpp: In constructor ‘zespolona::zespolona(numer)’:
k1.cpp:4: error: ‘ob’ has incomplete type
k1.cpp:1: error: forward declaration of ‘struct numer’
Jeśli wszystko zapakuję do pliku main.cpp to proces kompilacji przechodzi pomyślnie.
Ktoś by mógł powiedzieć, że skoro są to dwie proste klasy i taki prymitywny program, to dlaczego nie wpisać tego do jednego pliku (main.cpp). Dobrze można.
Ale co z tego jak w dalszym ciągu nie będę umiał poradzić sobie z wyżej wymienionym problemem?

Aha, przepisałem to w Dev-C++ tam program robi Makefile, ale ten także zwraca błędy podobne do wyżej wymienionych.

Z góry dziękuję za jakiekolwiek rady, propozycje, sugestie.

: 03 stycznia 2009, 22:29
autor: pietrzuch

Kod: Zaznacz cały

/tmp/ccOpUTWf.o: In function `main': 
main.cpp :( .text+0xe1): undefined reference to `zespolona: :p okaz()' 
collect2: ld returned 1 exit status
Komunikat oznacza że nie widzi takiej funkcji. Najprawdopodobniej jest to spowodowane złym includowaniem plików, dlatego ja stosuje zamiast *.cpp *.hpp. (mam tylko jedno main.cpp)
Dopisz w main.cpp:

Kod: Zaznacz cały

extern zespolona: :p okaz();
I powinno pomóc. ;-)

: 03 stycznia 2009, 22:38
autor: Theq
O sesja sie zbliza :) Pokaz caly kod to wskazemy bledy. Tak przy okazji, to opcja "-o" g++ wiaze sie z nazwa pliku wynikowego (nie ma nic wspolnego z plikami ".o").

[ Dodano: 2009-01-03, 22:55 ]
W ramach odswiezenia, prosty przyklad jak to zrobic:

Plik k1.h

Kod: Zaznacz cały

#ifndef K1_H
#define K1_H

class Zespolona
{
  private:
   int _r;
   int _u;

  public:
   int pokazR();
   int pokazU();
   Zespolona(int r = 0, int u = 0)
   {
     _r = r;
     _u = u;
   }
};

#endif
Plik k1.cpp

Kod: Zaznacz cały

#include "k1.h"

int Zespolona: :p okazR()
{
  return _r;
}

int Zespolona: :p okazU()
{
  return _u;
}
Plik main.cpp

Kod: Zaznacz cały

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

int main()
{
  Zespolona a, b(5, 1);

  std::cout << a.pokazR() << " " << a.pokazU() << std::endl;
  std::cout << b.pokazR() << " " << b.pokazU() << std::endl;
}
Kompilacja:

Kod: Zaznacz cały

g++ main.cpp k1.cpp -o zespolone

: 04 stycznia 2009, 00:25
autor: zygi151

Kod: Zaznacz cały

O sesja sie zbliza :) 
Nie zupełnie - nie studiuje - c++ to dla zaspokojenia ambicji ;p hi hi
lubię coś robić, więc wspaniały język daje dużo satysfakcji, co prawda jestem początkujący ale jak wszystko ogarnę to coś ciekawego napisze (mam nadzieję) - dobrze bo już chyba off topic.

Tak więc to się staram skompilować. Robiony na podstawie przykładu z Symfonia c++ str.775 (trochę bardziej uproszczony) faktycznie powinienem kompilować *.cpp, a nie tylko main,cpp. Tak więc ostatecznie błędy są trochę inne (przepraszam za podanie wcześniejszych, tym samym robienie 'zamieszania'). O to moje pliki.

K1.h

Kod: Zaznacz cały

#ifndef K1_h
#define K1_h
class numer;

#include <iostream>
using namespace std;
#include <string>


class zespolona
{
 double rzeczyw;
 double urojon;
public:
 zespolona(double r=0, double i=0 ) : rzeczyw(r), urojon(i) {}
 zespolona( numer  );
 friend zespolona dodaj(zespolona, zespolona);
 void pokaz();
};

#endif
k1.cpp

Kod: Zaznacz cały

class numer;
#include "k1.h"

zespolona::zespolona(numer ob)
{
 rzeczyw = ob.n ;
 urojon = 0 ;
}

void zespolona: :p okaz()
{
 cout << rzeczyw << endl << urojon << endl;
}
k2.h

Kod: Zaznacz cały

#ifndef K2_h
#define K2_h

class zespolona;

#include <iostream>
using namespace std;
#include <string>

class numer
{
 double n;
 string opis;
 friend zespolona::zespolona(numer);
public:
 numer(double k, string t="opis") : n(k), opis(t) {}
};

#endif
main.cpp

Kod: Zaznacz cały

#include <iostream>
#include "k1.h"
#include "k2.h"
using namespace std;

zespolona dodaj(zespolona a, zespolona b);

int main()
{
 zespolona a,c;
 a.pokaz();
 numer b(3.3, "napis");
 return 0;
}


zespolona dodaj(zespolona a, zespolona b)
{
 zespolona wynik;
 wynik.rzeczyw = a.rzeczyw + b.rzeczyw;
 wynik.urojon = a.urojon + b.urojon;
 return wynik;
};
kompilacja:

Kod: Zaznacz cały

zygi@debian-dawid:~/c/operator_kon$ g++ main.cpp k1.cpp -Wall -o zespol
k1.cpp: In constructor ‘zespolona::zespolona(numer)’:
k1.cpp:4: error: ‘ob’ has incomplete type
k1.cpp:1: error: forward declaration of ‘struct numer’
Jeśli wszystko jest wpisane w main.cpp w kolejności k1.h k2.h k1.cpp main.cpp - to wszystko jest w porządku.

: 04 stycznia 2009, 08:14
autor: grzesiek
Problem z logicznym łączeniem plików. Przetestowałem - dział.
k1.h

Kod: Zaznacz cały

#ifndef K1_h
#define K1_h
class numer;

#include <iostream>
using namespace std;
#include <string>


class zespolona
{
 double rzeczyw;
 double urojon;
public:
 zespolona(double r=0, double i=0 ) : rzeczyw(r), urojon(i) {}
 zespolona( numer  );
 friend zespolona dodaj(zespolona, zespolona);
 void pokaz();
};

#endif 
k1.cpp

Kod: Zaznacz cały

#include "k1.h"
#include "k2.h"

class numer;

zespolona::zespolona(numer ob)
{
 rzeczyw = ob.n ;
 urojon = 0 ;
}

void zespolona: :p okaz()
{
 cout << rzeczyw << endl << urojon << endl;
} 
k2.h

Kod: Zaznacz cały

#ifndef K2_h
#define K2_h

class zespolona;

#include <iostream>
using namespace std;
#include <string>

class numer
{
 double n;
 string opis;
 friend zespolona::zespolona(numer);
public:
 numer(double k, string t="opis") : n(k), opis(t) {}
};

#endif 
main.cpp

Kod: Zaznacz cały

#include <iostream>
#include "k1.cpp"
#include "k2.h"
using namespace std;

zespolona dodaj(zespolona a, zespolona b);

int main()
{
 zespolona a,c;
 a.pokaz();
 numer b(3.3, "napis");
 return 0;
}


zespolona dodaj(zespolona a, zespolona b)
{
 zespolona wynik;
 wynik.rzeczyw = a.rzeczyw + b.rzeczyw;
 wynik.urojon = a.urojon + b.urojon;
 return wynik;
}; 

: 04 stycznia 2009, 10:47
autor: Theq
[quote="zygi151"]Nie zupełnie - nie studiuje - c++ to dla zaspokojenia ambicji ]
W takim razie poczytaj o zaleznosciach cyklicznych (circular dependencies) i dlaczego unikac ich stosowania. Twoj kod to wlasnie przyklad takiej zaleznosci. No i powodzenia w dalszej nauce :)

k1.h

Kod: Zaznacz cały

#ifndef K1_h
#define K1_h

#include <iostream>
using namespace std;
#include <string>

class numer;

class zespolona
{
 double rzeczyw;
 double urojon;
public:
 zespolona(double r=0, double i=0 ) : rzeczyw(r), urojon(i) {}
 zespolona( numer  );
 friend zespolona dodaj(zespolona, zespolona);
 void pokaz();
};

#endif
k1.cpp

Kod: Zaznacz cały

#include "k1.h"
#include "k2.h"

zespolona::zespolona(numer ob)
{
 rzeczyw = ob.n ;
 urojon = 0 ;
}

void zespolona: :p okaz()
{
 cout << rzeczyw << endl << urojon << endl;
}
k2.h

Kod: Zaznacz cały

#ifndef K2_h
#define K2_h

#include <iostream>
using namespace std;
#include <string>

class zespolona;

class numer
{
 double n;
 string opis;
 friend zespolona::zespolona(numer);
public:
 numer(double k, string t="opis") : n(k), opis(t) {}
};

#endif 
main.cpp

Kod: Zaznacz cały

#include <iostream>
#include "k1.h"
#include "k2.h"

using namespace std;

zespolona dodaj(zespolona a, zespolona b);

int main()
{
 zespolona a,c;
 a.pokaz();
 numer b(3.3, "napis");
 return 0;
}


zespolona dodaj(zespolona a, zespolona b)
{
 zespolona wynik;
 wynik.rzeczyw = a.rzeczyw + b.rzeczyw;
 wynik.urojon = a.urojon + b.urojon;
 return wynik;
}

: 04 stycznia 2009, 12:23
autor: zygi151
Dziękuję wszystkim za odpowiedzi.
Odnośnie zależności cyklicznych znalazłem to:

http://en.wikipedia.org/wiki/Circular_dependency

Może komuś się przyda - "przyszłemu pokoleniu".