PDA

Visualizza la versione completa : [c++]inner class e observer


giuseppe500
08-02-2010, 10:14
ciao.
ho creato due classi che dialogano tra di loro implementando l'observer.
Ognuna di queste classi deve essere insieme un observer e un observable e per questo doppio comportamento ho utilizzato le inner class:
(non inserisco le classi astratte observer e observable)


class Flower : Observable {
bool isOpen;
public:
Flower() : isOpen(false) {}
void open() { // Opens its petals
string m_name = "pippo";
isOpen = true;
}
void close() { // Closes its petals
isOpen = false;
}
// Using the "inner class" idiom:
class FlowerObserver;
friend class Flower::FlowerObserver;
class FlowerObserver : public Observer {
Flower* parent;
void update(Observable* o, Argument * arg)
{
cout <<"flower" << arg->m_name;

};

public:

} FlowerObserver;
std::set<Observer*> observers;

void addObserver(Observer& o) {
observers.insert(&o);
}
void notifyObservers(Argument* arg=0) {

std::set<Observer*>::iterator it;
for(it = observers.begin(); it != observers.end(); it++){
(*it)->update(this, arg);
}
}
};



class Flower2 : Observable {
bool isOpen;
public:
Flower2() : isOpen(false) {}
void open() { // Opens its petals
isOpen = true;
}
void close() { // Closes its petals
isOpen = false;
}
// Using the "inner class" idiom:
class Flower2Observer;
friend class Flower2::Flower2Observer;
class FlowerObserver : public Observer {
Flower2* parent;
void update(Observable* o, Argument * arg)
{
cout << arg->m_name;
parent->open();
};

public:

}Flower2Observer;


std::set<Observer*> observers;

void addObserver(Observer& o) {
observers.insert(&o);
}
void notifyObservers(Argument* arg=0) {

std::set<Observer*>::iterator it;
for(it = observers.begin(); it != observers.end(); it++){
(*it)->update(this, arg);
}
}
};

int main() {

Flower f;
Flower2 f2;

f.addObserver(f2.Flower2Observer);
f2.addObserver(f.FlowerObserver);

Argument a;
Argument b;
f2.notifyObservers(&b);
f.notifyObservers(&a);



} /


il tutto sembra funzionare , il problema che quando notifico ad un qualsiasi observer e arrivo nell' update:



Flower2* parent;
void update(Observable* o, Argument * arg)
{
cout << arg->m_name;
parent->open();
};


vorrei avere un puntatore valido in parent alla classe flower2 instanziata , mentre mi viene sempre un puntatore non valido 0xccccccc per intenderci.
grazie.

MacApp
08-02-2010, 13:09
la variabile membro "parent" non viene mai inizializzata, quindi giustamente ti da un puntatore non valido.

Definisci il costruttore per la inner class che si prenda in arg il tipo di parent, e quindi lo invochi nel costruttore del padre.

insomma qualcosa di simile a (osserva che ho spostato sotto il costruttore di default):


class Flower : Observable {
class FlowerObserver : public Observer {
Flower* parent;
...

public:
FlowerObserver (Flower*theParent): parent(theParent){}
} FlowerObserver;
...
Flower() : isOpen(false), FlowerObserver (this) {}
...
};


p.s. evita di chiamare tipo e membri con lo stesso nome (anzi strano che te lo compili)

Loading