alovaros
alovaros

Reputation: 476

Creating List of abstract base class to fill with inherited objects

I want to create a List which is able to hold every Object I throw at it as long as they share the same ABSTRACT base class. Here is an sample code of how I want to achieve this.

#include <iostream>
#include <memory>
#include <list>

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


class RequestStateObserver
{
public:
void registerObserver(std::shared_ptr<Observer> o){
  observerList.push_back(o);
}
private:
std::list<std::shared_ptr<Observer>> observerList;  
};

class RestRequestCreator :Observer
{
  void update() override;
};
void RestRequestCreator::update()
{
  std::cout<<"RestRequestCreator::update()";
}

class dbHandler :Observer
{
  void update() override;
};
void dbHandler::update() {
  std::cout<<"dbHandler::update()";
}

int main()
{
 RestRequestCreator rrc;
 RequestStateObserver rso;
 dbHandler dbhandler;
 std::shared_ptr<RequestStateObserver> stateObserver;
 std::shared_ptr<RestRequestCreator> rr_ptr = std::make_shared<RestRequestCreator>(rrc);
 rso.registerObserver(rr_ptr);
 rso.registerObserver(std::make_shared<Observer> (dbhandler));
}

o->registerObserver(std::make_shared<Observer> dbhandler)will tell me I can't create Observer since it's an abstract class which totally makes sense but

o->registerObserver(rr_ptr) will tell me it can't convert std::shared_ptr<Observer> to std::shared_ptr<RestRequestCreator>

I am at the moment not sure how to fix this problem or what exactly I should try next. Would Templates help me? If I am correct they would just allow me to put as many objects of ONE child class into my List, if that's wrong please tell me and I will re-read about templates again.

Upvotes: 0

Views: 76

Answers (2)

Andreas_75
Andreas_75

Reputation: 64

Also: should an observee co-own an observer? In general that would not be the case. Therefore, instead use regular pointers.

#include <list>
#include <iostream>

using std::cout;

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

class ConcreteObserver : public Observer
{
public:
    void update() override { 
        cout << "ConcreteObserver noticed update\n";}
};

class OtherKindConcreteObserver : public Observer
{
public:
    void update() override {
        cout << "OtherKindObserver noticed update\n";
    }
};

class Subject
{
public:
    void registerObserver( Observer* o) {
        observerList.push_back( o);
    }

    void signalObservers() {
        for ( auto observer : observerList)
            observer->update();
    }
private:
    std::list<Observer*> observerList;  
};


int main() {
    ConcreteObserver           observer1;
    OtherKindConcreteObserver  observer2;
    Subject                    subject;

    subject.registerObserver( &observer1);
    subject.registerObserver( &observer2);

    subject.signalObservers();

    return 0;
}

Upvotes: 0

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32742

The conversion fails because Observer is a private base of RestRequestCreator, and is inaccessible.

You'll need to use public inheritance for the compiler to implicitly convert from the derived class to the base:

class RestRequestCreator :public Observer

That fixes the immediate problem, but leaves the problems with make_shared<Observable> on the next line.

Upvotes: 2

Related Questions