-2

The use is to provide .instance access, also to prevent duplicate objects of those classes.

Is this a good code implementation of a singleton?

template <typename T> class singleton
{
public:
    static T *ms_singleton;

    singleton()
    {
        assert(!ms_singleton);
        long offset = (long)(T *) 1 - (long)(singleton <T> *)(T *) 1;
        ms_singleton = (T *)((long) this + offset);
    }

    virtual ~singleton()
    {
        assert(ms_singleton);
        ms_singleton = 0;
    }

    static T &instance()
    {
        assert(ms_singleton);
        return (*ms_singleton);
    }

    static T &Instance()
    {
        assert(ms_singleton);
        return (*ms_singleton);
    }

    static T *instance_ptr()
    {
        return (ms_singleton);
    }
};
template <typename T> T *singleton <T>::ms_singleton = NULL;

How I use it:

class test1: public singleton<test2>
{
    // Something
};

If not, what is wrong here? What should i rewrite here?

Smartx221
  • 17
  • 5

1 Answers1

1

Your singleton class has some weird things. Like you relying on the constructor to do a debug-build run-time check that it can be constructed or not, in your constructor.

A typical singleton class have the constructors private so it can only be constructed by the accessor function. It also should not rely on e.g. assert which is a macro which is disabled in release builds.

A simple non-inheritable singleton class could look like this:

class Singleton
{
public:
    static Singleton& instance()
    {
        static Singleton actual_instance;
        return actual_instance;
    }

    // Other public member functions

private:
    // Private constructor
    Singleton() = default;
};

By having the constructor private, it means no one else can't attempt to construct an instance. It also means that this is checked at the time of compilation by the compiler itself.

Also by having the actual instance of the object as a static variable and initialized at definition inside the accessor function, mean that the creation of the instance is thread-safe.


To expand it and make it generic like you seem to want to do, then you need to make the base class constructor protected. You also need to make the base class a friend in the inherited class.

The child-class still need to make its constructor private to prevent accidental construction.

Updated the base class would then look something like

template<typename T>
class Singleton
{
public:
    static T& instance()
    {
        static T actual_instance;
        return actual_instance;
    }

protected:
    Singleton() = default;
};

A child class might look something like

class ChildSingleton : public Singleton<ChildSingleton>
{
public:
    // Public member functions...

private:
    friend class Singleton<ChildSingleton>;

    // Private constructor
    ChildSingleton() = default;
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621