How can you make different existing classes into "observers"?

C

craig

Given two existing but different classes OldA and OldB (that can not be
made to derive from any new base class); is there a way to make them
both "observer" objects so that they can be put in one central list and
updated thru a common interface. (i.e. observer->update( ..))?

Potential solution 1 (multiple inheritence): make a small new observer
class, and two new classes: NewA: derived from OldA, and Observer,..
and NewB: derived from OldB, and Observer. When walking thru a list of
NewA's and NewB's, cast the objects as Observer. (Can this even work?)
and call it's update function.

Potential solution 2 (composition): Make a new abstract composite class
"observer" and derive concrete observers ObserverA, and ObserverB that
contain "instances" of OldA, and OldB respectively. (The problem with
this approach in my case is that OldA is QtWidget and window management
becomes cumbersome.

Potential solution 3: Any other appraoches?

Any comments or rules-of-thumb greatly appreciated.

Thanks,
-Craig
 
J

Jim Langston

craig said:
Given two existing but different classes OldA and OldB (that can not be
made to derive from any new base class); is there a way to make them
both "observer" objects so that they can be put in one central list and
updated thru a common interface. (i.e. observer->update( ..))?

Potential solution 1 (multiple inheritence): make a small new observer
class, and two new classes: NewA: derived from OldA, and Observer,..
and NewB: derived from OldB, and Observer. When walking thru a list of
NewA's and NewB's, cast the objects as Observer. (Can this even work?)
and call it's update function.

Potential solution 2 (composition): Make a new abstract composite class
"observer" and derive concrete observers ObserverA, and ObserverB that
contain "instances" of OldA, and OldB respectively. (The problem with
this approach in my case is that OldA is QtWidget and window management
becomes cumbersome.

Potential solution 3: Any other appraoches?

This is how I do it.


class CGUIElement
{
...

// Observer Model
// OpenObserver listens for when a window Opens
class OpenObserver;
friend class CGUIElement::OpenObserver;

class OpenObserver : public Observer
{
CGUIElement* parent;
public:
OpenObserver(CGUIElement* GUIElement) : parent(GUIElement) {}
void update(Observable* /*Obs*/, Argument* Arg)
{
parent->SetOpen( true );
if ( parent->Type == GUI_List )
parent->ListIndex = dynamic_cast<OpenArgument*>(Arg)->Msg;
}
} OpenObserver;

...
}
 
D

Daniel T.

"craig said:
Given two existing but different classes OldA and OldB (that can not be
made to derive from any new base class); is there a way to make them
both "observer" objects so that they can be put in one central list and
updated thru a common interface. (i.e. observer->update( ..))?

Potential solution 1 (multiple inheritence): make a small new observer
class, and two new classes: NewA: derived from OldA, and Observer,..
and NewB: derived from OldB, and Observer. When walking thru a list of
NewA's and NewB's, cast the objects as Observer. (Can this even work?)
and call it's update function.

class Observer {
public:
virtual ~Observer() { }
virtual void update() = 0;
};

class NewA : public OldA, public Observer {
public:
void update() {
// call member-functions inherited from OldA
}
};

Potential solution 2 (composition): Make a new abstract composite class
"observer" and derive concrete observers ObserverA, and ObserverB that
contain "instances" of OldA, and OldB respectively. (The problem with
this approach in my case is that OldA is QtWidget and window management
becomes cumbersome.

class NewA : public Observer {
OldA* itsOldA;
public:
NewA( OldA* oldA ): itsOldA( oldA ) { }
~NewA() { delete itsOldA; }
void update() {
// call member-functions of itsOldA
}
};


I would only use the latter if the contained object doesn't need to be
shared. IE, if you need to put a getter in the NewA class to extract
itsOldA for use, then solution 2 is problematic. However, if OldA
already has classes derived from it that also must support the Observer
interface, then you have no choice and must go with solution 2.
Potential solution 3: Any other appraoches?

Is there some ABC that OldA is derived from?

class ParentOfOldA {
public:
virtual void func() = 0;
};

class OldA : public ParentOfOldA {
public:
void func();
};

class NewA : public Observer, public ParentOfOldA {
OldA* itsOldA;
public:
NewA( OldA* oldA ): itsOldA( oldA ) { }
~NewA() { delete itsOldA; }
void update() {
// call member-functions of itsOldA
}
};
 
C

craig

JIm, Thanks for the idea,..This looks interesting, but I don't
completely understand it (most likely due to my lack of C++
sophistication). It looks like you are nesting (embedding) an observer
inside the old object, which can be instanced externally as an
OpenObserver and added to a list of Observers. Then when you want to
call the update function you invoke CGUIElement::OpenObserver->update(
Arg ...) or something similar. If that's the jist of it, I don't quite
undestand what you're doing inside the update definition.
So if you're up to it, any paraphrasing would certainly help!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top