1

Let's say there's a class:

class X {
    public:
        static X& get_instance(int foo, int bar);
    private:
        X();
        int foo, bar;
}

If I wrote this correctly then get_instance is a named constructor. Now here's what I'm trying to do;

Let's create an instance of X;

X& first = X::get_instance(3, 5);
X& second = X::get_instance(4, 6);
X& third = X::get_instance(3, 5);

I want to write get_instance in such a way that, when it is called with the same parameters twice, instead of creating a new instance, it should just return a reference to the old one. When the instances created with parameters (3, 5) all get deleted, then creating a new instance with (3, 5) create a new instance.

I imagined this would be possible by overloading the equality test operator and keeping track of every object the constructor has created so far. But this is C++, and there has to be a better way to do it.

Barry
  • 286,269
  • 29
  • 621
  • 977
Berk Özbalcı
  • 3,016
  • 3
  • 21
  • 27

1 Answers1

1

Herb Sutter's favorite 10-liner, adjusted for slightly different arguments and removing the lock:

static std::shared_ptr<X> X::get_instance(int foo, int bar) {
    static std::map<std::pair<int, int>, std::weak_ptr<X>> cache;

    auto key = std::make_pair(foo, bar);     
    auto sp = cache[key].lock();
    if (!sp) cache[key] = sp = std::shared_ptr<X>(new X(foo, bar)); 
    return sp;
}

Can't use make_shared since the constructor is private, unless you use one of the tricks suggested on this question.

Community
  • 1
  • 1
Barry
  • 286,269
  • 29
  • 621
  • 977