Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared subservient object

I have a template class Foo that has a method, barMethod, that requires a Bar object. I could have each individual Foo object create Bar objects as needed, but I don't want to do that because it will be slow, and there is a good chance that different Foo objects could use the same Bar object.

Given that, I would like to have a BarManager object that has the existing set of Bar objects. The Foo objects could then ask it for Bar objects, and if an appropriate one already exists, the manager would simply return it. If it doesn't the manager would create a new one and return it.

It seems to me that there are two problems with implementing the "manager" approach.

  1. The manager would have to be a global variable, which I would prefer not to do.
  2. BarManager and Bar are both template classes, so even if I were to make the manager a global variable/object, I'm not sure how that would work. I guess I could make the global variable a void * and cast it whenever it is de-referenced to the appropriate templated class, but that seems really ugly.

There has to be a way to do this that isn't so ugly (perhaps using an auto pointer?). What is it?

EDIT: This software is part of a library that I (and perhaps others) will use later, which is why the classes are templated and the template type is not known a priori. Also, I want to keep things as simple as possible for the user of Foo, so I do not want the caller to have to do anything with BarManager or Bar (e.g. instantiating BarManager and giving the reference to each Foo).

like image 912
Jim Clay Avatar asked Sep 13 '26 01:09

Jim Clay


1 Answers

If you:

  1. Know concrete type of BarManager in compile time.
  2. Don't want any user of Foo knowing about this internal mechanism.

Then you can have all Foo classes holds this BarManager as a static (definitely not a global var)

template <typename T>
class Bar{};

template <typename T>
class BarManager;

template <typename T>
class Foo
{
private:
    static BarManager<T>& GetBarManager()
    {
        static BarManager<T> managerInstance;
        return managerInstance;
    }

public:
    void barMethod()
    {
        auto& bar = GetBarManager().GetBarInstance();

        // Do something with `bar`
    }
};

template <typename T>
class BarManager
{
public:
    Bar<T>& GetBarInstance()
    {
        // Replace with cacher implementation:
        static Bar<T> dud;
        return dud; 
    }
};

int main()
{
    Foo<int> foo;
    foo.barMethod();

    return 0;
}
like image 79
Geezer Avatar answered Sep 15 '26 16:09

Geezer