Problem z zakleszczeniem klas C++


(synaptyk) #1

Witam,
Mam problem ponieważ posiadając klasy
Magazyn

#ifndef MAGAZYN_H
#define MAGAZYN_H
#include "Klient.h"
class Magazyn
{
       static Lista<Klient> listaKlientow;
      public:
       static DodajNaKoncu(int);
}
#endif

i Klient

#ifndef KLIENT_H
#define KLIENT_H

#include "Magazyn.h"


using namespace std;

class Klient
{
public:
    Klient();
    DodajPrzesylke(){Magazyn::DodajNaKoncu(25);}
};
#endif

Wywala wiele błędów error: ‘Klient’ was not declared in this scope


(Fizyda) #2

Na pewno problem leży w tym kodzie który załączyłeś? Nie brakuje przypadkiem klasy gdzie indziej?
Za godzinkę do tego wrócę, spróbuję to skompilować i dam znać.


(synaptyk) #3

Trochę skróciłem ten kod, ale nie sądzę by coś innego to powodowało


(synaptyk) #4

Gdy na w Klient.h zamiast #include "Magazyn.h" wstawię class Magazyn; to wszystkie odwołania do nieistniejącej klasy Klient znikają i pojawia się tylko jeden błąd error: incomplete type 'Magazyn' used in nested name specifier


(Fizyda) #5

Przepraszam, zeszło mi się trochę dłużej niż myślałem.

Nie możesz mieć takiej sytuacji jaką masz, takiego kodu nie da się skompilować bo dochodzi do zakleszczenia. To jest błąd projektowy. Jeśli dochodzi Ci do sytuacji, że jedna klasa wymaga drugiej i druga pierwszej to masz coś mocno źle przemyślane w architekturze aplikacji.

Poza tym, nie wiem czemu magazyn składa się tylko z właściwości i metod statycznych - to błąd. Drugim błędem może być lista klientów magazynu, ale to jeszcze też zależy.


(synaptyk) #6

Dodałem nową niezależną klasę i póki co działa dobrze.

Nie ma żadnego sposobu by z Klienta bezpośrednio można by posługiwać się klasą Magazyn?
Tak by było logicznie, bo Klient wysyła paczkę od razu do magazynu bez korzystania z funkcji pomocniczych.

Co do magazynu, to dlaczego wszystko statyczne jest błędem?


(Fizyda) #7

Może i paczka trafia do magazynu, ale czy sam ją zawozi i układa na półce, dodaje do rejestru w magazynie i w ogóle obsługuje magazyn?

Na świecie masz tyko jeden magazyn czy wiele? Metody statyczne mają coś robić na rzecz klasy, magazyn nie jest typem a realnym obiektem. W twoim programie nie tworzysz żadnego magazynu.
Jeśli w programie chcesz mieć jeden globalny magazyn to lepiej zastosować wzorzec singleton, ale i on nie jest do końca dobrą praktyką projektową. Lepiej przekazywać przez referencję magazyn wszędzie tam gdzie jest potrzebny - w ten sposób łatwiej testować kod.


(synaptyk) #8

Akurat na potrzeby projektu jeden magazyn jest zupełnie wystarczający i łatwo się nim posługiwać gdzie go potrzeba.

Oprócz klienta mam jeszcze Administratora i Kuriera, ale ich listy też są w Magazynie więc wyręczyć się nimi nie mogę


(Fizyda) #9

Głowy sobie uciąć nie dam, ale przebłysk miałem jak zmienisz metodę Klient::DodajPrzesyłke() z inlnie na normalną i jej definicję dasz do cpp oraz przeniesiesz includa magazynu z hpp do cpp to możliwe, że zadziała.

Przepraszam, jak wprowadzam ostatnio w błąd, albo się mylę, ale mam sporo ważnych rzeczy na głowie.


(synaptyk) #10

Specjalnie skróciłem kod do inline, ale to działa tak samo w pliku .cpp


(Fizyda) #11

Nie tworzy się kodu na potrzeby jednego projekty, ale taki który można będzie później wykorzystać. Zmieni się problem i będziesz miał dwa magazyny i nagle masz do przepisania 1/4 projektu.

Więc powinieneś wykorzystać dziedziczenie i polimorfizm. W tedy też nie miałbyś problemu z pierwszego posta.

To nie jest skracanie kodu!!! Funkcja inline jest zupełnie inaczej traktowana przez kompilator!

Wszystko o czym piszesz i próbujesz bronić niestety utwierdza w tym, że program jest źle zaprojektowany. Takich błędów z czasem będziesz miał coraz więcej, aż niemożliwe będzie ogarnięcie tego bez przepisania aplikacji.