0

I have a singleton, for example:

#include <bits/stdc++.h>

class A { 
 private:
  A() {printf("init a unparam A\n");}
  virtual ~A() = default;

 public:
  static A& Inst() { static A u; return u;} 
  void print() {printf("my no = %d\n", no_);}
  int no_ = -1;
};

I know this is odd; in most situations, I only need one in my program. However, in some cases, I need several objects in one program, so I added a constructor with an int parameter.

#include <bits/stdc++.h>

class A { 
 private:
  A() {printf("init a unparam A\n");}
  A(int i) : no_(i) { printf("init a A with no = %d\n", no_);}  // this part is added
  virtual ~A() = default;

 public:
  static A& Inst() { static A u; return u;} 
  static A& Inst(int i) { static A u(i); return u;}   // added
  void print() {printf("my no = %d\n", no_);}
  int no_;
};

In main.cpp:

int main() {
  A & a = A::Inst();
  a.print();
  A & b = A::Inst(1);
  b.print();
  A & c = A::Inst(2);
  c.print();
}

The result is:

init a unparam A
my no = 0
init a A with no = 1
my no = 1
my no = 1  // Inst(2) only get the Inst(1) object, why?

In my opinion, the first a will create a Inst by calling the no parameter constructor, b will create one with no=1, c create one with no=2.

But the real result is, b and c share one object.

Could you help on this? How can I make this work?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
nick
  • 832
  • 3
  • 12

1 Answers1

3

Note: I don't advice anyone to do it this way, I'm merely providing a solution for OP's question to create multiple object with the singleton pattern.


Singleton has been having some bad reputation: What are drawbacks or disadvantages of singleton pattern? [closed]

Now you want to further break the "Singleton" by making it a "Pluralton", I would only assume it's worse.


Nonetheless, the reason you are not getting your expected result is because this line will only run once:

static A u(i);

This is a static local variable, which mean it will only be initialized for the first time it was called in the function.


One way to workaround is by making static A& Inst(int i) a templated function, where i is being templated, so that each call with a different i will generation a new function:

template<int I>
static A& Inst() {
    static A u(I); 
    return u; 
}

Now you can call it like:

A & a = A::Inst<1>();
a.print();
A & b = A::Inst<1>();
b.print();
A & c = A::Inst<2>();
c.print();
A & d = A::Inst<2>();
d.print();

And it will print:

init a A with no = 1
my no = 1
my no = 1
init a A with no = 2
my no = 2
my no = 2
Ranoiaetep
  • 5,872
  • 1
  • 14
  • 39