Poprawne includowanie, problem z klasami

0

Piszę swój nieduży projekt i napotkałem na problem, którego nie potrafię rozwiązać.
Mam dwie klasy: Pociag i Stacja. Klasa Pociag ma dwa pola typu Stacja (początkowa i docelowa), natomiast klasa Stacja ma pole typu Pociąg (bo przechowuje pociągi, które na tej stacji stoją). Problem polega na tym, że nie mogę poprawnie dołączyć tych plików do siebie, żeby kompilator nie rzucał mi błędem class type redefinition. Próbowałem użyć #pragma once i jakiś guardów, które znalazłem w Internecie, ale nic nie rozwiązało mojego problemu. Dodam jeszcze, że oba pliki (klasy Stacja i Pociag) dołączam później w pliku main.cpp.

0

Nie ma żadnego powodu, żeby pociąg miał stację, lub stacja miała pociąg, a tak wynika z twojego opisu. Do stacji przypisane jest wiele różnych pociągów, ale stacja nie ma do nich własności, podobnie do pociągu przypisane są różne stacje, więc w obydwu przypadkach zrób np. vector wskaźników. Pociągi oraz stacje powinieneś przechowywać w jakimś zewnętrznym kontenerze (pewnie vector znów się nada). Jak użyjesz wskaźników to nie potrzebujesz dołączać definicji klasy, tylko deklarację ("forward declaration").

0

Moim zdaniem to błędny podział klas. Ja zrobiłbym klasę, która odpowiadałaby za konkretną trasę pociągu. Miałaby ona przypisane te dwie stacje oraz pociąg, jaki na niej kursuje.

W takim kształcie jak teraz zapewne potrzebujesz deklaracji zapowiadającej przed deklaracją klasy.

0
Zjarek napisał(a):

Pociągi oraz stacje powinieneś przechowywać w jakimś zewnętrznym kontenerze (pewnie vector znów się nada).

Chodzi o kontener, który będzie przechowywał stację i przypisane do niej pociągi?

Zjarek napisał(a):

Jak użyjesz wskaźników to nie potrzebujesz dołączać definicji klasy, tylko deklarację ("forward declaration").

W tym momencie właśnie takie rozwiązanie zastosowałem i wszystko się kompiluje, jednak, gdy np. do jednej z metod przekazuję Pociag* pociag i chcę wywołać jakąś metodę, używając tego wskaźnika (np. pociag->jedz_do(Stacja stacja) ) to kompilator wyrzuca mi błąd "use of undefined type Pociag"

Endrju napisał(a):

Moim zdaniem to błędny podział klas. Ja zrobiłbym klasę, która odpowiadałaby za konkretną trasę pociągu. Miałaby ona przypisane te dwie stacje oraz pociąg, jaki na niej kursuje.

W takim kształcie jak teraz zapewne potrzebujesz deklaracji zapowiadającej przed deklaracją klasy.

Taki podział wydał mi się naturalny, ponieważ moim zadaniem jest zaprogramowanie symulatora stacji kolejowej :-).

0
Trobin napisał(a):

Taki podział wydał mi się naturalny, ponieważ moim zadaniem jest zaprogramowanie symulatora stacji kolejowej :-).

I widzisz jakie to powoduje problemy.

Trobin napisał(a):

W tym momencie właśnie takie rozwiązanie zastosowałem i wszystko się kompiluje, jednak, gdy np. do jednej z metod przekazuję Pociag* pociag i chcę wywołać jakąś metodę, używając tego wskaźnika (np. pociag->jedz_do(Stacja stacja) ) to kompilator wyrzuca mi błąd "use of undefined type Pociag"

Jeżeli już użyłeś deklaracji zapowiadających to nie powinno być takich problemów. W końcu musisz gdzieś includować ten plik nagłówkowy, żeby kompilator wiedział o co chodzi:

  • W plikach nagłówkowych klas używasz tylko deklaracji zapowiadających.
  • W plikach źródłowych klas includujesz obydwa pliki nagłówkowe.

Oczywiście wymaga to takiego rozdziału (deklaracja i definicja klasy osobno), być może go nie zastosowałeś?

0
Endrju napisał(a):
Trobin napisał(a):

Taki podział wydał mi się naturalny, ponieważ moim zadaniem jest zaprogramowanie symulatora stacji kolejowej :-).

I widzisz jakie to powoduje problemy.

Trobin napisał(a):

W tym momencie właśnie takie rozwiązanie zastosowałem i wszystko się kompiluje, jednak, gdy np. do jednej z metod przekazuję Pociag* pociag i chcę wywołać jakąś metodę, używając tego wskaźnika (np. pociag->jedz_do(Stacja stacja) ) to kompilator wyrzuca mi błąd "use of undefined type Pociag"

Jeżeli już użyłeś deklaracji zapowiadających to nie powinno być takich problemów. W końcu musisz gdzieś includować ten plik nagłówkowy, żeby kompilator wiedział o co chodzi:

  • W plikach nagłówkowych klas używasz tylko deklaracji zapowiadających.
  • W plikach źródłowych klas includujesz obydwa pliki nagłówkowe.

Oczywiście wymaga to takiego rozdziału (deklaracja i definicja klasy osobno), być może go nie zastosowałeś?

Nie zastosowałem, bo osobiście wydaje mi się bzdurą, która zmniejsza czytelność kodu (a przyzwyczajenia mam z innego języka programowania :-) ), ale widzę, że pisząc w C++ będę musiał się przemóc. Spróbuję rozdzielić każdą klasę na dwa pliki i zobaczę co się stanie. Tak czy inaczej dzięki za podpowiedzi :-).

Edit: po zastosowaniu rozdziału plików klasy na pliki .h i .cpp działa :-). Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1