Hello to all, i have coded an observer pattern

class IObserver;

class ISubject
{
public:

public:
 ISubject();
 virtual ~ISubject();

 virtual void RegisterObserver(IObserver*) = 0;
 // Observer only interest in certain aspect
 virtual void RegisterObserver(IObserver*, bool) = 0;

 virtual void UnRegisterObserver(const IObserver*) = 0;
 
 // An Observer with 1 subject 
 virtual void NotifyObserver() = 0;
 // An Observer with many subject
 virtual void NotifyObserver(const ISubject&) = 0;

};

class IObserver
{

public:
 IObserver();
 virtual ~IObserver();


 virtual void Update(ISubject*) = 0; 
 // Observer only interest in certain aspect
 //virtual void Update();


};


class Subject : public ISubject
{
public:

 Subject();
 Subject(size_t);
 ~Subject();

 void RegisterObserver(IObserver*);
 void RegisterObserver(IObserver*, bool);

 void UnRegisterObserver(const IObserver*);
 

 void NotifyObserver();
 void NotifyObserver(const ISubject&);


 void setValue(const size_t&);
 size_t getValue() const;

private:

 size_t value;
 std::vector<IObserver*> cont;

};

Observer::Observer() 
{
}
// =============================================
Observer::~Observer()
{
}
// =============================================
void Observer::Update(ISubject* observSubject)
{
// Error Here
 cout << observSubject->getValue();
}

error C2027: use of undefined type 'ISubject'
error C2227: left of '->getValue' must point to class/struct/union/generic type

Please help.

Thanks.

Recommended Answers

All 4 Replies

I'm assuming that the posted code are just snippets...So I'll assume that you've declared/defined an Observer class and actually defined the getValue function.....Both of those are missing from the posted code...

Looking at the rest of the code, the only other thing that seems odd is the fact that the getValue function is a member of the derived class Subject, but is not a member of the base class ISubject.

Bearing that in mind...
Where you're using a pointer to an ISubject object in your Observer::Update function, I don't think the getValue function will be visible to the ISubject pointer.

But if you make the getValue function a virtual or pure virtual member of the base class ISubject, then the version delcared in the Subject class should get treated as a polymorphic override and will therefore be called. So if the ISubject pointer points to an instance of a Subject object, then the Subject::getValue will be called in the Observer::Update function....At least, that's how it looks to me, judging by the snippets you've posted!

If that's not the solution to the problem, perhaps .zip up your code and attach it here so we can take a more detailed look!

Cheers for now,
Jas.

dynamic_cast

void IObserver::Update(ISubject* observSubject){
  cout <<  dynamic_cast<Subject*>(observSubject)->getValue();
}

dynamic_cast

void IObserver::Update(ISubject* observSubject){
  cout <<  dynamic_cast<Subject*>(observSubject)->getValue();
}

Hmm, using dynamic_cast is an option. But if the OP ends up creating several different classes derived from ISubject, then it would make more sense to make the getValue function a virtual in the base class and then override it in all derived classes. That way the code in Observer::Update remains short and succinct.

void Observer::Update(ISubject * obsevSubject)
{
    cout << observSubject->getValue();
}

Otherwise they'd have to perform several dynamic_casts to check every possible type. So you'd have to do something like this:

void Observer::Update(ISubject* observSubject)
{
    size_t output;
    if(dynamic_cast<Subject*>(observSubject))
        output =  dynamic_cast<Subject*>(observSubject)->getValue();
    else if (dynamic_cast<OtherSubject*>(obsevSubject))
        output = dynamic_cast<OtherSubject*>(observSubject)->getValue();
    else if ........ // ad nauseum for every derived type

   cout << output;
}

So dynamic_cast is an option if there aren't likely to be many classes derived from ISubject, but personally I'd probably still go with using a virtual in the base class!

Alternatively, if the getValue function is common to all derived classes and returns the same type of variable, then it may be worth percolating the functionality upwards into the base class!
i.e. make getValue a base class function and make value a member variable in the base class too!

Cheers for now,
Jas.

I have try to code with virtual in base class but the things is ISubject is an abstract class. Compile pop out error undefined type.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.