2

I would like to have a class T that can generate only 1 instance in the whole program.

Now i know about std::unique_ptr but there are 2 problems:

  • it's limited to a scope ( but it's not a big issue ... )
  • it needs to be explicitly used, meaning that it's not part of the class or the type, it's just and handler and a special pointer, but it does not modify the design of my class.

now i would like to have class T designed in a way that not even by mistake the user can declare 2 instances in the same program and i can't rely on the fact that my user will declare an std::unique_ptr for T because i want to solve this by design.

right now i'm only thinking about how to make an implicit use of an unique_ptr in an elegant way, the problem is that i do not have any clue at the moment.

the other way around is to check if this class is handled by an unique_ptr but this check will make me lose an edge in terms of performances.

since having only 1 instance is really important, i see only 2 options in my case: 1) trying to solve this by design 2) throwing errors at compile time with some sort of check/macro.

I know that this looks trivial but with a design approach it's not, at least for me, so please help.

axis
  • 874
  • 2
  • 7
  • 13
  • 1
    The word you look for is `singleton`. – poitroae Oct 08 '12 at 19:32
  • http://www.yolinux.com/TUTORIALS/C++Singleton.html – tpg2114 Oct 08 '12 at 19:32
  • 2
    You are looking for singleton, but probably more proper and modern way would be to use static class (as in: class with only static members) or just namespace. – Griwes Oct 08 '12 at 19:32
  • 2
    Why do you want just *one* object of that type? What would be the problem with having multiple ones? – Xeo Oct 08 '12 at 19:34
  • @Xeo it's an object that will contain vital settings for the app, it must be unique to avoid runtime errors or user frustration when dealing with multiple objects for the same settings. – axis Oct 08 '12 at 19:35
  • 1
    @Xeo: The question of why having multiple instances is bad is not the important question. There are many legitimate reasons why an app should never have more than once instance of certain types of objects. For example, expensive resources, connections, etc. The *real* question is: why should you have to reply on engineering tricks to ensure your clients don't do stupid stuff? – John Dibling Oct 08 '12 at 19:37
  • 2
    @JohnDibling, there are no; if the class shouldn't have more than *one* instance, it should have *no* instances and you would get the same functionality with less ugly syntax (something::get_singleton()->do_something() vs something::do_something(); I prefer the latter). – Griwes Oct 08 '12 at 19:41
  • 1275 possible duplicates: http://stackoverflow.com/search?q=%5Bc%2B%2B%5D+singleton – Tom Kerr Oct 08 '12 at 19:44
  • @Griwes: I don't rightly understand what you're saying. – John Dibling Oct 08 '12 at 19:49
  • @JohnDibling, read also my previous comment. – Griwes Oct 08 '12 at 19:53
  • 1
    @Griwes: Ah, I see. Yes, valid point. Yet another reason why a Singleton is an anti-pattern. Just to play Devil's Advocate though, it's possible that one would need RAII type functionality that doesn't rely on calling a `disconnect()` type method at shut-down. – John Dibling Oct 08 '12 at 19:56

3 Answers3

4

What you're looking for is called the Singleton pattern, and while it is widely considered by many (myself included) to be an anti-pattern, I will nonetheless show you the basic elements needed to build one.

Basically what you need to do is provide three things:

  1. A static method which "gets" the one and only instance
  2. A private constructor, so that nobody can ever instantiate it
  3. (optional) A means by which the one and only instance is created before main starts

Here's the essential code:

class Singleton
{
public:
  Singleton&  get() 
  { 
    static Singleton me_;
    return me_;
  }
private:
  Singleton() {};
};

I leave it to you to discover how to implement #3 above, and why you shouldn't be using a Singleton in the first place -- there are many reasons.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • The OP didn't say anything about caring when the only instance gets created, and since singleton also does not care when the creation occurs, only that it must occur before it is given to anyone, I don't see why you put #3 in your list at all... – Cdaragorn Oct 08 '12 at 20:14
  • The explicit conditional and dynamic allocation is a bit silly. You get the exact same behaviour from a `static` variable (including thread-safety). – Kerrek SB Oct 08 '12 at 20:17
  • @Cdaragorn: Completeness. Keep in mind that my answer isn't just for the benfit of the person who asked the question, but for all future visitors as well. – John Dibling Oct 08 '12 at 20:17
  • I was thinking of a block-static variable actually, because that also gives you definite initialization order. – Kerrek SB Oct 08 '12 at 20:20
  • static Singleton me_; is not allowed in header file as per MISRA C++ rules. We need to use below solution in this case. – Mehmet Fide Jun 08 '13 at 15:34
3

This is typically referred to as a Singleton.

See http://en.wikipedia.org/wiki/Singleton_pattern

The typical trick in C++ is to have a function which returns the singleton instance by reference, and make the constructor private.

Something like:

#include <iostream>
using namespace std;

class Foo
{
private:
  Foo() : a(3) { a++; }
  static Foo singleton;
  int a;
public:
  static Foo& getFoo() { return singleton; }
  void doStuff() { cout<<"My a is: "<<a<<endl; }
};

Foo Foo::singleton;

int main(int argc, char** argv)
{
  Foo::getFoo().doStuff();
  Foo &foo = Foo::getFoo();
  foo.doStuff();

  //uncomment below to cause compile error                                                                                                                                                                                                                                                                                                                                
  //Foo foo2;                                                                                                                                                                                                                                                                                                                                                             
}

Note that in real code you'll split this up into a header and a cpp file. In that case the

Foo Foo::singleton;

part must go in the cpp file.

Soverman
  • 1,135
  • 1
  • 9
  • 16
2

You could have at least

 static int count;
 assert(count == 0);
 count++;

in the constructor(s) of the singleton class. This don't ensure at compile time that your class is singleton, but at least it checks that at runtime.

And you could also make the constructor private, and have a static member function returning (once) a pointer to your instance, perhaps something like

 class Singleton {
 private:
    Singleton() {
      static int count;
      assert(count == 0);
      count++;
    };
    Singleton(Singleton&) = delete;
 public:
    static Singleton* the_instance() {
      static Singleton* it;
      if (!it) it = new Singleton();
      return it;
    }
 };
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • so you are going for the runtime check basically ? The problem is that after an X amount of time spent with your compiler, if your code will not work you probably will be pissed off with the creator of the library ... – axis Oct 08 '12 at 19:33
  • 2
    you should disable default copy constructors and alike as well. See also http://stackoverflow.com/a/271104/1025391 – moooeeeep Oct 08 '12 at 19:35