algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Dekorator (decorator) - Implementacja w C/C++
Ocena użytkownikóww: *****  / 8
SłabyŚwietny
Nadesłany przez Kamil Dworak, 14 sierpnia 2010 22:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

dekorator.cpp:
/****************************************
*   Wzorzec Projektowy Decorator        *
*   (dekorator)                         *   
*   www.algorytm.org                    *
*   Opracowal Dworak Kamil              *
*****************************************/

#include <iostream>
#include <string>
using namespace std;

    /* Standardowy nieudekorowany samochod */
class Samochod {
	protected:
		string samochod;
		double wartosc;
    	
	public:
		Samochod(){
			samochod = "Samochod podstawowy";
			wartosc=0;
		}

		virtual string about(){
			return samochod;
		}
    	
		virtual double cena(){
			return wartosc;
		}
};

    /* abstrakcyjny dekorator */
    class Dekorator : public Samochod {

	public:
        virtual string about(){
                return "hmm";
                }
        };

    /* teraz mamy 2 przykladowe marki samochodow */
    class Mercedes : public Samochod {

	public: Mercedes():Samochod(){
		    samochod = "Mercedes";
			wartosc=500000;
	    }
    	
};

    class Fiat : public Samochod {
	
	public: Fiat():Samochod(){
		    samochod = "Fiat";
			wartosc=100000;
	    }
    	
};

    /* czas na same dodatki */
    class Klimatyzacja : public Dekorator {
		Samochod *car;
    	
	public: Klimatyzacja(Samochod *samochod):Dekorator(){
            car = samochod;
	    }
    	
	     string about(){
            return car->about() + " + klimatyzacja";
	    }
    	
	     double cena(){
			 return car->cena()+1111;
	    }
};

    class OponyZimowe : public Dekorator {
	Samochod *car;
	
	public: OponyZimowe(Samochod *samochod):Dekorator(){
        car = samochod;
	}

     string about()
    {
        return car->about() + " + opony zimowe";
	}
	
	/* niech ceny beda takie same */
     double cena()
    {
        return car->cena() + 31234;
	}
};


	int main(){

        Samochod *s1 = new Mercedes();
		Samochod *s2 = new Fiat();
		
		cout<<"\nBez wyposazenia"<<endl;
        cout<<s1->about()<<" "<<s1->cena()<<endl;
        cout<<s2->about()<<" "<<s2->cena()<<endl;
		
		//dodajemy po klimie
		s1 = new Klimatyzacja(s1);
		s2 = new Klimatyzacja(s2);
        cout<<"\nZ Klima"<<endl;
        cout<<s1->about()<<" "<<s1->cena()<<endl;
        cout<<s2->about()<<" "<<s2->cena()<<endl;
		
		// i opony

		s1 = new OponyZimowe(s1);
		s2 = new OponyZimowe(s2);
        cout<<"\nZ oponami"<<endl;
        cout<<s1->about()<<" "<<s1->cena()<<endl;
        cout<<s2->about()<<" "<<s2->cena()<<endl;
		
		//od razu tworzymy wyposazony samochod
        cout<<"\nPelne wyposazenie"<<endl;
		Samochod *s3 =  new OponyZimowe( new Klimatyzacja( new Mercedes()));
        cout<<s3->about()<<" "<<s3->cena()<<endl;

        system("PAUSE");
return 0;
}
Komentarze
photo
0 # BRY 2015-06-09 11:09
Wszystko okej, ale jak ogarnac te alokowane obiekty?
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
+5 # Lemjur 2015-09-15 05:24
Czy przed przypisaniem do s1 i s2 nowych obiektów, nie powinniśmy zwolnić obiektów? Wszak operator New alokuje nowe bloki pamięci i ustawia na nich wskaźnik.
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # SKC 2017-06-08 15:07
No właśnie nie. Klimatyzacja i OponyZimowe to wersje dekoratora. Konstruktor dekoratora zachowuje wskaźnik do obiektu z parametru i używa go potem w funkcjach about i cena. Wiec usunąć go na tym etapie nie można :) Po zakończniu pracy z obiektami można by posprzątać dla porządtku i jawnie pozwalaniać pamięć, ale i tak po zakończaniu main zrobi się to samo. Zresztą to przykład do dekorowania tylko.
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Dudoxxx 2018-06-06 13:46
Trzeba pamiętać, że wskaźniki do tych obiektów s1 i s2 alokowanych na początku dla samochodów są teraz składowymi klas dodatków. Pytanie czy trzeba coś tu zwalniać i czy potrzeba wirtualnych destruktorów :)
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Jaco 2016-11-13 16:55
Zdecydowanie nie powinniśmy zwalniać obiektów spod s1 i s2 przed przypisaniem do nich nowych. W końcu wskaźniki są przekazywane do konstruktora klasy Klimatyzacja oraz potrzebujemy tych obiektów na dalszą część programu. Powinniśmy natomiast zwolnić je na koniec programu. Tyle tylko, że nie mamy już do nich dostępu przez s1 i s2 a przez wskaźnik car więc w destruktorze klas Klimatyzacja i OponyZimowe powinna znaleźć się instrukcja "delete car". Oczywiście, wciąż, na końcu programu powinny być kasowane obiekty spod s1, s2, i s3, które wskazują już na nowe obiekty. Poprawiony i lekko zmodyfikowany przykład znajdziecie na moim GitHubie: https://github.com/Jaco32/Dekorator
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Pacze i widze 2017-06-29 23:59
A załóżmy teraz, że mamy klasę KomisSamochodow y (jakiś tam kontener, np dziedziczący po std::list) i chcemy zrobić upust cenowy dla wszystkich aut, które mają klimatyzację na dodatkowym wyposażeniu? Taki model totalnie blokuje implementację podobnych funkcjonalności . Jak np. dowiedzieć się, czy obiekt s3 posiada klimatyzację?
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz