++ /dynamiczna zmiana implementacji klasy??

0

Witam:) Mam problem:) posaidam takie zadanie:

Zdefiniować klasę bazowa Subject zawierającą trzy funkcje f(), g() i h(). Następnie z klasy tej wyprowadzić
klasy Implementation1, Implementation2 i Proxy. Ta ostatnia powinna zawierać wskaźnik do
obiektu typu Subject, a wszystkie jej metody powinny zwracać i być wywoływane na rzecz wskaźnika
takiego właśnie typu obiektu. Konstruktor klasy Proxy powinien inicjalizować wskaźnik do typu
Subject zainstalowanego w jej wnętrzu. W programie głównym zdefiniować dwa różne obiekty Proxy,
posiadające inna implementacje. Następnie zmodyfikować klasę Proxy w sposób umożliwiający
dynamiczna zmiane implementacji tej klasy.

oto fragment kodu:

#include <cstdlib>
#include <iostream>

using namespace std;
class Subject
{
public:
       Subject(){};
       ~Subject(){};
       void f(){cout<<"\n Funkcja f z klasy Subject\n";}; //funkcja
       void g(){cout<<"\n Funkcja g z klasy Subject\n";}; //funkcja
       void h(){cout<<"\n Funkcja h z klasy Subject\n";}; //funkcja   
};
/////////////////////////////////////////////////////////
class Implementation1: public Subject
{
public:
       Implementation1(){};
       ~Implementation1(){};
       void f(){cout<<"\n Funkcja f z klasy Implementation1\n";};//funkcja
       void g(){cout<<"\n Funkcja g z klasy Implementation1\n";};//funkcja
       void h(){cout<<"\n Funkcja h z klasy Implementation1\n";}; //funkcja
};
/////////////////////////////////////////////////////////
class Implementation2: public Subject
{
public:
       Implementation2(){};
       ~Implementation2(){};
       void f(){cout<<"\n Funkcja f z klasy Implementation2\n";};//funkcja
       void g(){cout<<"\n Funkcja g z klasy Implementation2\n";};//funkcja
       void h(){cout<<"\n Funkcja h z klasy Implementation2\n";}; //funkcja
};
/////////////////////////////////////////////////////////
class Proxy: public Subject
{
public:
       Subject *wsk;   //wskaźnik do obiektu typu Subject
       Proxy(Subject x);
       ~Proxy(){};
       Subject*  f();  //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
       Subject* g();   //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
       Subject* h();   //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
};
/////////////////////////////////////////////////////////
Proxy::Proxy(Subject x):wsk(&x)
{
//wsk=&x; //to samo co w liscie inicjalizacyjnej           
}
/////////////////////////////////////////////////////////
Subject* Proxy::f()
{ 
Subject* obiekt1;   

return obiekt1;               
}
/////////////////////////////////////////////////////////
Subject* Proxy::g()
{
Subject* obiekt2;

return obiekt2;                 
}
/////////////////////////////////////////////////////////
Subject* Proxy::h()
{
Subject* obiekt3;

return obiekt3;                   
}
/////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
    system("PAUSE");
    return EXIT_SUCCESS;
}

moj problem plega na tym ze nie rozumiem zbytnio " W programie głównym zdefiniować dwa różne obiekty Proxy, posiadające inna implementacje. Następnie zmodyfikować klasę Proxy w sposób umożliwiający dynamiczna zmiane implementacji tej klasy."

czy ktos moglby mi to wyjasnic i dokonczyc zaczety kod?? z gory dzieki

Pozdrawiam

0

Hm... poczytaj o interfejsach w c++?

0

Tak bym to zmienił:

#include <cstdlib>
#include <iostream>

using namespace std;
class Subject
{
public:
       Subject(){};
       virtual ~Subject(){};
       // nie pisze, co funkcje mają zwracać... ułatwmy sobie życie,
       // niech zwracają this. Przy okazji, Subject niech będzie klasą
       // abstakcyjną, niech dopiero Implementation1,2 wprowadza
       // ciało funkcji f,g,h
       virtual Subject* f() = 0;
       virtual Subject* g() = 0;
       virtual Subject* h() = 0;
};
/////////////////////////////////////////////////////////
class Implementation1: public Subject
{
public:
       Implementation1(){ };
       ~Implementation1() { cout<<"\n ~Implementation1\n"; };
       virtual Subject* f(){cout<<"\n Funkcja f z klasy Implementation1\n"; return this; }
       virtual Subject* g(){cout<<"\n Funkcja g z klasy Implementation1\n"; return this; }
       virtual Subject* h(){cout<<"\n Funkcja h z klasy Implementation1\n"; return this; }
};
/////////////////////////////////////////////////////////
class Implementation2: public Subject
{
public:
       Implementation2(){};
       ~Implementation2() { cout<<"\n ~Implementation2\n"; };
       virtual Subject* f(){cout<<"\n Funkcja f z klasy Implementation2\n"; return this; }
       virtual Subject* g(){cout<<"\n Funkcja g z klasy Implementation2\n"; return this; }
       virtual Subject* h(){cout<<"\n Funkcja h z klasy Implementation2\n"; return this; }
};
/////////////////////////////////////////////////////////
class Proxy: public Subject
{
private:
       Subject *wsk;   //wskaźnik do obiektu typu Subject
public:
       Proxy(Subject* x);
       // zakładamy, że Proxy jest właścicielem wskaźnika, niech sam
       // więc dba o jego zwolnienie
       ~Proxy(){ delete wsk; };
       Subject*  f();  //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
       Subject* g();   //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
       Subject* h();   //metody zwracajace i wywoływane na rzecz wskaźnika *wsk
};
/////////////////////////////////////////////////////////
Proxy::Proxy(Subject* x) : wsk(x)
{
}
/////////////////////////////////////////////////////////
Subject* Proxy::f()
{
return wsk->f();
}
/////////////////////////////////////////////////////////
Subject* Proxy::g()
{
return wsk->g();
}
/////////////////////////////////////////////////////////
Subject* Proxy::h()
{
return wsk->h();
}
/////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
    {
    Proxy jeden(new Implementation1);
    Proxy dwa(new Implementation2);

    dwa.f()->g()->h();
    jeden.f()->g()->h();
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
0

ee.. chyba to nie tak.. wydaje mi sie ze proxy powinien od razu udawac obiekt docelowy

cos a'la:

class Interface
{public:
    virtual void metoda() = 0;
};

class Impl1 : public Interface
{public:
    void metoda() { cout << "1" << endl; }
}

class Impl2 : public Interface
{public:
    void metoda() { cout << "2" << endl; }
}

class Proxy : public Interface
{public:
    Proxy(Interface* im, bool own){impl=im;owned=own;}
    ~Proxy(){if(owned)delete impl;}
    void change(Interface* im){ if(owned)delete impl; impl = im; owned=own;}
    void metoda() { if(impl) impl->metoda; }
private:
    bool owned;
    Interface* impl;
};

int main()
{
    Proxy raz(new Impl1(), true);    //pierwotna implementacja: Impl1

    raz->metoda();
    raz->metoda();

    raz.change(new Impl2(), true);   //dynamiczna zmiana na Impl2

    raz->metoda();
    raz->metoda();
}

edit:
aah, wybaczcie. dopiero po napisaniu i wyslaniu zauwazylem ze u Was THIS jest zwracane i stad ta zabawa z ->F()->G().

aale -- Ranides -- Twoj kod nie umozliwial dynamicznej podmiany, jedynie podczas konstrukcji, wiec zostawiam moje powyzsze z trywialna zmiana wzgledem tego co zaproponowales

0

quetzalcoatl nie moge stsowac funkcji wirtualnych w zadnej klasie....zadanie jest typowo dla dziedziczenia bez zastosowania funkcji wirtualnych...wie codpada....jednak wczesnia koncepcja wydaje sie prawidlowa....

a co to znaczy dynamiczna zmiana implementacji klasy????

0

poprawilem juz zadanie....troche nie tak jak pisaliscie ale skorzystalem z waszych raddddd:)

pozdrawiam:)

0
#include <cstdlib>
#include <iostream>
using namespace std;

class Subject
{
public:
       /* nie pisze, co funkcje mają zwracać... ułatwmy sobie życie, niech zwracają this. Przy okazji, Subject niech 
       będzie klasą abstakcyjną, niech dopiero Implementation1,2 wprowadza ciało funkcji f,g,h*/
       virtual Subject* f()=0;
       virtual Subject* g()=0;
       virtual Subject* h()=0;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Implementation1 : public Subject
{
public:
       virtual Subject* f(){cout<<"\n\t Funkcja f z klasy Implementation1\n"; return this; }
       virtual Subject* g(){cout<<"\n\t Funkcja g z klasy Implementation1\n"; return this; }
       virtual Subject* h(){cout<<"\n\t Funkcja h z klasy Implementation1\n\n\n"; return this; }
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Implementation2 : public Subject
{
public:
       virtual Subject* f(){cout<<"\n\t Funkcja f z klasy Implementation2\n"; return this; }
       virtual Subject* g(){cout<<"\n\t Funkcja g z klasy Implementation2\n"; return this; }
       virtual Subject* h(){cout<<"\n\t Funkcja h z klasy Implementation2\n\n\n"; return this; }
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Proxy : public Subject
{
private:
    Subject *wsk;
public:
       Proxy(Subject* x):wsk(x){}
       //zakładamy, że Proxy jest właścicielem wskaźnika, niech sam więc dba o jego zwolnienie
       ~Proxy(){delete wsk;}
       void zmiana_implementacji(Subject* x){delete wsk; wsk=x;}
       Subject* f(){return wsk->f();}   //metody zwracajace i wywoływane na rzecz wskaźnika do obiektu typu Subject
       Subject* g(){return wsk->g();}   //metody zwracajace i wywoływane na rzecz wskaźnika do obiektu typu Subject
       Subject* h(){return wsk->h();}   //metody zwracajace i wywoływane na rzecz wskaźnika do obiektu typu Subject
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
Proxy obiekt1(new Implementation1());    /*pierwotna implementacja: Implementation1 - najpier operator new stworzy obiekt 
                         i zwróci jego adres ktory jest argumentem dla konstruktora klasy Proxy, powstaje obiekt klasy Proxy*/ 
Proxy obiekt2(new Implementation2());    /*pierwotna implementacja: Implementation1*/


cout<<"\n WYWOLANIE METOD DLA OBIEKT1 i OBIEKT2\n";
cout<<"\n Dla obiektu 1:\n";
obiekt1.f()->g()->h();  //this jest zwracane i stad ta zabawa z ...f()->g()->h()
cout<<"\n Dla obiektu 2:\n";
obiekt2.f()->g()->h();


cout<<"\n ZMIANA IMPLEMENTACJI - (obiekt1)\n";
obiekt1.zmiana_implementacji(new Implementation2());   //dynamiczna zmiana obiektu na Implementation2
obiekt1.f()->g()->h();  //this jest zwracane i stad ta zabawa z ...f()->g()->h()


cout<<"\n ZMIANA IMPLEMENTACJI - (obiekt2)\n";        
obiekt2.zmiana_implementacji(new Implementation1());   //dynamiczna zmiana obiektu na Implementation1
obiekt2.f()->g()->h();
   
system("PAUSE");
return EXIT_SUCCESS;
}

Oto rozwiazanie

0

Oto rozwiazanie

No co ty nie powiesz 8-O
Ani ja, ani queztalcoatl nigdy byśmy na to nie wpadli, gratuluję samodzielności ;]

0

nie to mialem kolego na mysli....wykorzystalem wasza wieeeelka wiedze:) bo widac ze Kubus pojecia nie ma
i pewnie nie polaczyl kodu....nie denerwuj sie czlowieku tak:)

0

dzieki Miakin za caly kod....mialem bleda i go poprawilem.....:)

0
quetzalcoatl napisał(a)
class Interface
{public:
    virtual void metoda() = 0;
};

class Impl1 : public Interface
{public:
    void metoda() { cout << "1" << endl; }
}

class Impl2 : public Interface
{public:
    void metoda() { cout << "2" << endl; }
}

class Proxy : public Interface
{public:
    Proxy(Interface* im, bool own){impl=im;owned=own;}
    ~Proxy(){if(owned)delete impl;}
    change(Interface* im){ if(owned)delete impl; impl = im; owned=own;}
    void metoda() { if(impl) impl->metoda; }
private:
    bool owned;
    Interface* impl;
};

int main()
{
    Proxy raz(new Impl1(), true);    //pierwotna implementacja: Impl1

    raz->metoda();
    raz->metoda();

    raz.change(new Impl2(), true);   //dynamiczna zmiana na Impl2

    raz->metoda();
    raz->metoda();
}

Oooo... to jest wypas! RESPECT [!!!]

0

jak sie bledy poprawi to dziala.... bo zapomnial napisac czy cos funkcja change zwraca czy nie....

0

1' kod pisalem z palca i bez testowania, tylko aby pokazac idee.. moga byc bledy tak jak w/w opisany

2' egon - jesli to byla ironia - nie rozumiem czemu.. jak sa jakies bledy - patrz pkt1), napisz co to poprawie, jesli nie ironia - thx, nic wielkiego

3' kubus.. zdecyduj sie.. raz piszesz

quetzalcoatl nie moge stsowac funkcji wirtualnych w zadnej klasie....zadanie jest typowo dla dziedziczenia bez zastosowania funkcji wirtualnych...wie codpada....jednak wczesnia koncepcja wydaje sie prawidlowa....

a potem dziekujesz Miakin'owi za kod, w ktorym az roi sie od virtual'i

4' kubus - trudno zrobic DYNAMICZNA podmiane implementacji bez WYWOLAN WIRTUALNYCH. Nawet to co zaproponowano na samym poczatku i co rozwinal Ranides chodzi na wywolaniach wirt..

5' Ranides - tez mi szczeka opadla jak zobaczylem kod i "oto.." :)

6' Miakin - bez urazy, zabawne to bylo po prostu

0

Dobra chlopaki.... i tak jestescie wielcy!!!:) nie prowadzmy rozmowy do niepotrzebnych spiec.... a Miakinowi dzieki za caly kod <klaniam_sie> bo pomoglo mi to.... a WAM dzieki za caaaly pomysl<bije_poklony> wieksze niz do Miakin'a :) jestem zielony w tych sprawach i moze namieszalem z tym wirtualem wiec sorki...musze jeszcze troche poczytac....

PEACE WSZYSTKIM:)

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