Alex Gaynor
Alex Gaynor

Reputation: 14989

Global instance of a class in C++

As the title says. How would I create an instance of a class that is globally available(for example I have a functor for printing and i want to have a single global instance of this(though the possibility of creating more)).

Upvotes: 12

Views: 44304

Answers (7)

Cyber Oliveira
Cyber Oliveira

Reputation: 8596

The simplest and concurrency safe implementation is Scott Meyer's singleton:


#include <iostream>

class MySingleton {
public:
    static MySingleton& Instance() {
        static MySingleton singleton;
        return singleton;
    }
    void HelloWorld() { std::cout << "Hello World!\n"; }
};

int main() {
    MySingleton::Instance().HelloWorld();
}

See topic IV here for an analysis from John Vlissides (from GoF fame).

Upvotes: 0

deft_code
deft_code

Reputation: 59269

I prefer to allow a singleton but not enforce it so in never hide the constructors and destructors. That had already been said just giving my support.

My twist is that I don't use often use a static member function unless I want to create a true singleton and hide the constr. My usual approach is this:

template< typename T >
T& singleton( void )
{
   static char buffer[sizeof(T)];
   static T* single = new(buffer)T;
   return *single;
}

Foo& instance = singleton<Foo>();

Why not use a static instance of T instead of a placement new? The static instance gives the construction order guarantees, but not destruction order. Most objects are destroyed in reverse order of construction, but static and global variables. If you use the static instance version you'll eventually get mysterious/intermittent segfaults etc after the end of main.

This means the the singletons destructor will never be called. However, the process in coming down anyway and the resources will be reclaimed. That's kinda tough one to get used to but trust me there is not a better cross platform solution at the moment. Luckily, C++0x has a made changes to guarantee destruction order that will fix this problem. Once your compiler supports the new standard just upgrade the singleton function to use a static instance.

Also, I in the actual implemenation I use boost to get aligned memory instead of a plain character array, but didn't want complicate the example

Upvotes: 0

Loki Astari
Loki Astari

Reputation: 264331

First off the fact that you want global variables is a 'code smell' (as Per Martin Fowler).

But to achieve the affect you want you can use a variation of the Singleton.
Use static function variables. This means that variable is not created until used (this gives you lazy evaluation) and all the variables will be destroyed in the reverse order of creation (so this guarantees the destructor will be used).

class MyVar
{
    public:
        static MyVar& getGlobal1()
        {
            static MyVar  global1;
            return global1;
        }
        static MyVar& getGlobal2()
        {
            static MyVar  global2;
            return global2;
        }
        // .. etc
}

Upvotes: 5

Swapnil
Swapnil

Reputation: 299

Singleton is nice pattern to use but it has its own disadvantages. Do read following blogs by Miško Hevery before using singletons.

  1. Singletons are Pathological Liars

  2. Root Cause of Singletons

  3. Where Have All the Singletons Gone?

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 992717

Going to all the effort of making a singleton object using the usual pattern isn't addressing the second part of your question - the ability to make more if needed. The singleton "pattern" is very restrictive and isn't anything more than a global variable by another name.

// myclass.h

class MyClass {
public:
    MyClass();
    void foo();
    // ...
};

extern MyClass g_MyClassInstance;

// myclass.cpp

MyClass g_MyClassInstance;

MyClass::MyClass()
{
    // ...
}

Now, in any other module just include myclass.h and use g_MyClassInstance as usual. If you need to make more, there is a constructor ready for you to call.

Upvotes: 22

Mike Kale
Mike Kale

Reputation: 4133

As a slight modification to the singleton pattern, if you do want to also allow for the possibility of creating more instances with different lifetimes, just make the ctors, dtor, and operator= public. That way you get the single global instance via GetInstance, but you can also declare other variables on the heap or the stack of the same type.

The basic idea is the singleton pattern, however.

Upvotes: 1

Joel Martinez
Joel Martinez

Reputation: 47751

the Singleton pattern is what you're looking for.

Upvotes: 0

Related Questions