ďťż
 
 
   [+] C++ - kompilacja kilku plików
 
 

Tematy

 
    
 

 

 

 

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





zygi151 - 03-01-2009 21:39
Mam kilka plików do kompilacji mianowicie:
    lk1.h
    k1.cpp
    k2.h
    main.cppl
W k1.cpp znajdują się definicje 2 funkcji.
Podczas kompilowania (z pliku main.cpp wyłączam funkcje które są definiowane w k1.cpp): 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: /tmp/ccOpUTWf.o: In function `main':
main.cpp:(.text+0xe1): undefined reference to `zespolona::pokaz()'
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): void zespolona::pokaz()
{
 cout << rzeczyw << endl << urojon << endl;
} Próbowałem też kompilować w ten sposób: g++ k1.cpp main.cpp -Wall -o main.o ale dostawałem takie błędy: 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.



pietrzuch - 03-01-2009 22:29
/tmp/ccOpUTWf.o: In function `main':
main.cpp:(.text+0xe1): undefined reference to `zespolona::pokaz()'
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:
extern zespolona::pokaz(); I powinno pomóc. ;-)



Theq - 03-01-2009 22:38
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
#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
#include "k1.h"

int Zespolona::pokazR()
{
  return _r;
}

int Zespolona::pokazU()
{
  return _u;
} Plik main.cpp
#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:
g++ main.cpp k1.cpp -o zespolone



zygi151 - 04-01-2009 00:25
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 #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 class numer;
#include "k1.h"

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

void zespolona::pokaz()
{
 cout << rzeczyw << endl << urojon << endl;
} k2.h #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 #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: 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.



grzesiek - 04-01-2009 08:14
Problem z logicznym łączeniem plików. Przetestowałem - dział.
k1.h
#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
#include "k1.h"
#include "k2.h"

class numer;

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

void zespolona::pokaz()
{
 cout << rzeczyw << endl << urojon << endl;
} k2.h
#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
#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;
};



Theq - 04-01-2009 10:47

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ę)
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
#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
#include "k1.h"
#include "k2.h"

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

void zespolona::pokaz()
{
 cout << rzeczyw << endl << urojon << endl;
} k2.h
#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
#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;
}



zygi151 - 04-01-2009 12:23
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".
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • minister.pev.pl

  •  

     


     

     
    Copyright 2003. MĂłj serwis