*this
home about contact feed
projects
vagra vaBlo
categories
C++(7) Solaris(4) tntnet(3) vi(3) Linux(2) DeleGate(2) Postgres(2) proxy(2) cxxtools(1) regex(1) readline(1) dtrace(1) gcc(1) MeeGo(1) ssh(1) firefox(1)

How does C++ behave when instantiate singleton templates

Singleton template instantiation

When you create a sigleton, you want to have exact one instance in your programm. But what does happen if you have a singleton template that get instantiated multiple times. I did a simplified test to show what happens.

A singleton is an object, that can only be instantiated once in your program. Since it's a well known pattern i will assume you already know about or will easily find other information sources if you need further explatation.

When instancing a sigleton template, you might expect that you get one sigleton per template instance, but this is only partial true. An other assumation could be, that you can only have one template instance in your program, but this als also not right. Instead you get one singelton instance per type.

To demonstrate that behaviour, i use a simplified singleton template, it ignores multithreading, as well defaut operators, it's for demonstation only, not for use.

template <typename Object>
class Singleton
{
        Singleton() {}
        Singleton(const Object& s)
        {
                content = s;
        }
        Object content;

    public:
        static Singleton& getInstance(const Object& s)
        {
                static Singleton* instance = NULL;

                if(!instance)
                {
                        instance = new Singleton(s);
                }
                return *instance;
        }

        Object getValue()
        {
                return content;
        }
};

Now lets create 3 instances, first with string, second with wstring, which is just a different type and a third using string again.

#include <string>
#include <iostream>
#include "singleton.h"

int main(void)
{
        std::string s1("foo");
        std::wstring s2(L"foobar");
        std::string s3("bar");

        Singleton<std::string>& singla = Singleton<std::string>::getInstance(s1);
        std::cout << singla.getValue() << std::endl;

        Singleton<std::wstring>& singlb = Singleton<std::wstring>::getInstance(s2);
        std::wcout << singlb.getValue() << std::endl;

        Singleton<std::string>& singlc = Singleton<std::string>::getInstance(s3);
        std::cout << singlc.getValue() << std::endl;

        return 0;
}

Running that code shows, that you get 2 singletons, the first is Singleton<std::string>, the second is Singleton<std::wstring>. Any further instantiation of Singleton<std::string> or Singleton<std::wstring> will not create a further singleton as shown by singlc.

$ $CXX -o test test.cpp 
$ ./test   
foo
foobar
foo

If you arware of that behaviour, you can take advantage of it. However, you should keep in mind, that it could become very difficult to maintain such usage in larger projects. Others (typically you 6 months later) could try to create a singleton of the same type, unaware of the existence of the first instance. The outcome will be unpleasant, and you will get no warning from your compiler.

Write comment