1

I would like to write a ServiceLocator design pattern class in C++. The aim is to provide three methods :

CServiceLocator::push(obj);
CServiceLocator::get<IObjType>();
CServiceLocator::getAll<IObjType>();

I prefer keep a reference instead of pointers of objects. So I would like to use a std::vector of references objects. In order to do that, I make a std::vector but I can't compile and I see on the web that I can't cast a reference into a (void*).

Here is the code of my class :

class CServiceLocator
{
public:
    virtual ~CServiceLocator(){}

    template <class T>
    static void push(T &object)
    {
        m_objectList.push_back((void*)object);
    }

    template <class T>
    static T & get()
    {
        for (std::vector<void*>::iterator it = m_objectList.begin(); it != m_objectList.end(); it++)
        {
            //on essaie de faire un dynamic cast pour trouver le premier objet du bon type
            try
            {
                T & obj = (T&)dynamic_cast<T>(*it);
                return obj;
            }
            catch (std::bad_cast &)
            {
                //il n'est pas du bon type
            }
        }
    }

    template <class T>
    static std::vector<T&> & getAll()
    {
        std::vector<T&> result;

        for (std::vector<void*>::iterator it = m_objectList.begin(); it != m_objectList.end(); it++)
        {
            //on essaie de faire un dynamic cast pour trouver les objets du bon type
            try
            {
                T & obj = (T&)dynamic_cast<T>(*it);
                result.push_back(obj);
            }
            catch (std::bad_cast &)
            {
                //il n'est pas du bon type
            }
        }
        return result;
    }

private:
    CServiceLocator() {}
    static std::vector<void*> m_objectList;
};

Here is a usage example of expected result

A a;
B b;

CServiceLocator::push<A>(a);
CServiceLocator::push<B>(b);
A &a1 = CServiceLocator::get<A>();

Any one has idea on how to do that ?

lgm42
  • 591
  • 1
  • 6
  • 29
  • 2
    [std::reference_wrapper](http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) – bolov Aug 12 '14 at 07:11
  • `A a();` does not create an object. It declares a function named `a`, which returns an object of type `A`, and takes no arguments. To create an object using the default constructor, leave off the parens. i.e. `A a;` or `B b;` – Benjamin Lindley Aug 12 '14 at 07:27
  • You're right and it is corrected but it is not the aim of the question... – lgm42 Aug 12 '14 at 07:32
  • That's why it wasn't an answer, but a comment. – Benjamin Lindley Aug 12 '14 at 07:33

1 Answers1

3

You cannot directly make a std::vector of references.

If you wish to accomplish something approximating this, you have two options:

  • I didn't know std::reference_wrapper. But How I use it because I have to put every object indise ? Can I cast a std::reference_wrapper into a void* ? – lgm42 Aug 12 '14 at 07:16
  • Arf, std::reference_wrapper is available only for c++ 11 and my compiler for my target is no longer maintained and has not been migrated to c++ 11 ... – lgm42 Aug 12 '14 at 07:25