C++ i dzielenie programu na moduły - wieczne błędy

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
sznajder
Sędziwy Jeż
Sędziwy Jeż
Posty: 57
Rejestracja: 05 cze 2008, 15:18
Płeć: Mężczyzna
Wersja Ubuntu: 12.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Wrocław
Kontakt:

C++ i dzielenie programu na moduły - wieczne błędy

Post autor: sznajder »

Witam, może tytuł trochę nie bardzo ale nie wiedziałem jak to inaczej nazwać. Ćwiczę dzielenie programu na moduły i napotkałem problem którego nie mogę ominąć. Stworzyłem trzy pliki. Oto one:
test.cpp:

Kod: Zaznacz cały

#include <iostream>

using namespace std;

#include "symbol.hpp"

int main()
{

return 0;
}
symbol.hpp

Kod: Zaznacz cały

#ifndef SYMBOLE_HH
#define SYMBOLE_HH

#include <iostream>
using namespace std;

enum Symbol { e, a, b, c, d };

Symbol tab_dod[5][5] = {{e,a,b,c,d},{a,d,e,b,c},{b,e,c,d,a},{c,b,d,a,e},{d,c,a,e,b}}; 
Symbol tab_mno[5][5] = {{e,e,e,e,e},{e,d,c,a,b},{e,c,d,b,a},{e,a,b,c,d},{e,b,a,c,d}}; 
Symbol tab_ode[5][5] = {{e,b,a,d,c},{a,e,d,c,b},{b,c,e,a,d},{c,d,b,e,a},{d,a,c,b,e}};
Symbol tab_dzi[5][4] = {{e,e,e,e},{c,d,a,b,},{d,c,b,a},{b,a,c,d},{a,b,d,c}};

#endif
symbol.cpp

Kod: Zaznacz cały

#include "symbol.hpp"

Symbol operator +(Symbol z1, Symbol z2)
{
return tab_dod[z1][z2];
}

Symbol operator *(Symbol z1, Symbol z2)
{
return tab_mno[z1][z2];
}

Symbol operator -(Symbol z1, Symbol z2)
{
return tab_ode[z1][z2];
}

Symbol operator /(Symbol z1, Symbol z2)
{
if(z2 != e)
return tab_dzi[z1][z2];
else
  {
    cerr << endl << "    Blad! Proba dzielenia przez czynnik neutralny dodawania" << endl<< endl;
    return e;
  }
}

istream &  operator >> (istream &  StrmWej, Symbol &  WczytSym)
{
  Symbol TabSymboli[] = {a,b,c,d,e};
  char   ZnakSymbolu;
  
  StrmWej >> ZnakSymbolu;
  if (ZnakSymbolu < 'a' || 'e' < ZnakSymbolu) {
    cerr << "Blad! Wprowadzony znak nie odpowiada zadnemu symbolowi."
         << endl;
  }
  WczytSym =  TabSymboli[ZnakSymbolu-'a'];
  return StrmWej;
}

ostream & operator << ( ostream & StrmWy, Symbol x )
{
  StrmWy << "eabcd"[x];
  return StrmWy;
}
Program próbuję kompilować następującymi poleceniami:
g++ -c test.cpp
g++ -c symbol.cpp
g++ -o test test.o symbol.o

I ciągle dostaję w odpowiedzi błędy o następującej treści:

symbol.o:(.data+0x0): multiple definition of `tab_dod'
test.o:(.data+0x0): first defined here
symbol.o:(.data+0x80): multiple definition of `tab_mno'
test.o:(.data+0x80): first defined here
symbol.o:(.data+0x100): multiple definition of `tab_ode'
test.o:(.data+0x100): first defined here
symbol.o:(.data+0x180): multiple definition of `tab_dzi'
test.o:(.data+0x180): first defined here
collect2: ld returned 1 exit status

Kod programu to zwykłe podstawy niemniej jednak nie mam pojęcia dlaczego kompilator mówi że jest powtórna definicja tablic. Zwracam uwagę na to, że zastosowałem instrukcje warunkowe preprocesora.
Jeżeli komuś uda się to skompilować to prosiłbym o polecenia jakimi to skompilował. Całkiem możliwe, że jest tutaj jakiś banalny błąd którego akurat w tym momencie nie widzę. Z góry dziękuję za pomoc. Pozdrawiam
Awatar użytkownika
dawwin
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 202
Rejestracja: 18 kwie 2009, 09:16
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Re: C++ i dzielenie programu na moduły - wieczne błędy

Post autor: dawwin »

Błąd

Kod: Zaznacz cały

multiple definition of `tab_dod'
Oznacza, że zdefiniowałeś taką tablicę więcej niż raz. W tym konkretnym przykładzie ten twój zestaw zmiennych globalnych umieściłeś w headerze, czyli zostanie on dodany do dwóch plików *.cpp, które masz. Jeśli chcesz tego uniknąć to w pliku main.cpp umieść

Kod: Zaznacz cały

Symbol tab_dod[5][5] = {{e,a,b,c,d},{a,d,e,b,c},{b,e,c,d,a},{c,b,d,a,e},{d,c,a,e,b}};
Symbol tab_mno[5][5] = {{e,e,e,e,e},{e,d,c,a,b},{e,c,d,b,a},{e,a,b,c,d},{e,b,a,c,d}};
Symbol tab_ode[5][5] = {{e,b,a,d,c},{a,e,d,c,b},{b,c,e,a,d},{c,d,b,e,a},{d,a,c,b,e}};
Symbol tab_dzi[5][4] = {{e,e,e,e},{c,d,a,b,},{d,c,b,a},{b,a,c,d},{a,b,d,c}};
A w symbol.cpp

Kod: Zaznacz cały

extern Symbol tab_dod[5][5];
extern Symbol tab_mno[5][5];
extern Symbol tab_ode[5][5];
extern Symbol tab_dzi[5][4];
Słowo kluczowe extern informuje, że taki obiekt jst już gdzieś indziej zdefiniowany ( w tym przypadku w main.cpp) .
I tak przy okazji - zmiennych globalnych nie powinno się używać bez konkretnego powodu - nadmiar globali robi bałagan w programie
sznajder
Sędziwy Jeż
Sędziwy Jeż
Posty: 57
Rejestracja: 05 cze 2008, 15:18
Płeć: Mężczyzna
Wersja Ubuntu: 12.10
Środowisko graficzne: Unity
Architektura: x86_64
Lokalizacja: Wrocław
Kontakt:

Re: C++ i dzielenie programu na moduły - wieczne błędy

Post autor: sznajder »

Faktycznie trzeba było w pliku źródłowym inicjalizować te tablice. Akurat w moim programie te tablice musiały być globalne. Dzięki za pomoc. Problem rozwiązany.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości