Obiekt klasy pochodnej w klasie bazowej

0

Cześć, mam utworzoną klasę bazową oraz klasę która dziedziczy po niej. Chciałbym, aby klasa bazowa miała jako składową obiekt klasy dziedzicznej. Program ma mieć takie założenie że w klasie Wytwornia chce mieć metodę która sprzedaje produkt (przenosząc obiekt klasy Produkt z wektora magazynWytwornia do wektora magazynMiasto) a następnie chce aby klasa Lombard miała możliwość kupowania produktu (przenosząc obiekt klasy Produkt z wektora magazynMagazyn do wektora magazynLombard). Zależy mi aby dwie klasy dziedziczyły od siebie ponieważ mam tam dużo metod operujących na produktach. Aktualnie mam coś takiego napisanego. Zdaje sobie sprawę że nie ma prawa to działać bo najpierw kompiluję się klasa Wywornia w której obiekt klasy dziedzicznej z Wytwórni, której kompilator jeszcze nie zna. Jednak nie mam pojęcia co mogę zrobić aby to działo. Ma ktoś jakieś rady?
Plik Wytwornia.h

class Wytwornia
{
public:
    Wytwornia(float = 500000);
    Lombard l1; // wiem wiem ze to tak wygladac nie moze
//rożne metody

protected:
    std::vector<std::unique_ptr<Produkt>> magazynWytwornia;
    std::vector<std::unique_ptr<Produkt>> magazynMiasto;

private:
    float budzetWytwornia;
};

Plik Wytwornia.cpp

Wytwornia::Wytwornia(float budzetWytwornia) : budzetWytwornia(budzetWytwornia)
{
}

Plik Lombard.h

class Lombard : public Wytwornia
{
public:
    Lombard(float = 200000);

private:
    float budzetLombard;
    std::vector<std::unique_ptr<Produkt>> magazynLombard;
};

Plik Lombard.cpp

Lombard::Lombard(float budzetLombard) : budzetLombard(budzetLombard)
{

}
3

Popraw design. Z jakiej racji wytwórnia ma posiadać lombard i nim zarządzać? Ponadto, czemu lombard ma mieć także magazyn wytwórni i miasta?
Nie wiem, wydziel jakiś wspólny interfejs, dołóż metodę przyjmującą referencję do lombardu jako parametr...

0
alagner napisał(a):

Popraw design. Z jakiej racji wytwórnia ma posiadać lombard i nim zarządzać?

Uznałem że chce tak zrobić ponieważ chce aby wytwórnia i lombard miały takie same metody np jak zmieńCene, zmienKolor, pokazMagazyn itp. Więc uznałem że tak będzie łatwiej. Też zaczynam zauważać, że mój pomysł może mieć wady, ale napisałem już sporo kodu, który musiałbym teraz zmienić, więc liczyłem że uda się to zrobić w taki sposób jak sobie zaplanowałem

2

Jeżeli coś jest wspólne to najlepiej to wydzielić i używać w różnych kontekstach. Jak młotek przydaje się do remontowania i ubijania kotletów to w celu reużycia wolisz mieć młotek i osobne narzędzia niż młotek sklejony z solniczką i taśmą malarską, bo może się przydać.

3
kamkadz5z napisał(a):

chce aby wytwórnia i lombard miały takie same metody np jak zmieńCene, zmienKolor, pokazMagazyn

Lombard.zmienKolor ???

Ale nawet gdyby obronić te metody, to nie powód aby masakrować te dwie klasy, ale (najmniej zły) jakiś wspólny przodek

A w ogóle całe bicie piany jest o kant robić, wzmiankujesz coś o klasie Produkt, po czym dokumentujesz bez niej.

0

Może coś w ten deseń:

class Product
{
	
};

class Stock
{
    private:
    std::vector<std::unique_ptr<Produkt>> stock;
    public:
};

class Funds
{
    private:
    uint65_t money; // in cents
	public:
	Money 	
    static uint65_t encodeMoney(double m) { return (uint65_t)(100*m); }
    static double decodeMoney(uint65_t m) { return m/100.0; }
    Funds(uint65_t m):money(m) {}
    Funds(double m):Funds(encodeMoney(m)) {}
};

class City:public Stock,public Funds
{
    public:
    City(uint64_t m=500000):Funds(m) {}
};

class Lombard:public Stock
{
    private:
    Stock stock;
};

class Plant:public Stock,public Funds
{
    public:
    Plant(uint64_t m=500000):Funds(m) {}
};


int main()
{
    return 0;
}
0

Zapominajac o zasadnosci pomyslu (a chyba nigdy czegos podobnego ani sam nie popelnilem ani nie przypominam sobie zebym gdziekolwiek widzial), to nie widze odpowiedzi od strony czysto technicznej. A rozwiazaniem jest oczywiscie wskaznik, np:

class Lombard;

class Wytwornia {
    std::unique_ptr<Lombard> l1;
};
2
kamkadz5z napisał(a):

Uznałem że chce tak zrobić ponieważ chce aby wytwórnia i lombard miały takie same metody np jak zmieńCene, zmienKolor, pokazMagazyn itp. Więc uznałem że tak będzie łatwiej.

Dwa latka temu na CppCon była prezentacja "Back to Basics: Object-Oriented Programming ". Jeden z końcowych wniosków, tu widoczny, to "Use OOP to model 'is-a' relationships, no for code-reuse".
Tzn. tylko jeśli Lombard jest Wytwórnią (Lombard is-a Wytwórnia), to powinien z niej dziedziczyć. Przyoszczędzenie na pisaniu kodu nie jest powodem do dziedziczenia.

PS. zachęcam do obejrzenia całości jeśli dajesz sobie radę z angielskim.

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