0

I have a generic Singleton class that I'll use for many singleton classes. The generic class is giving a compile error when converting from a pointer to reference.

Error 3 error C2440: 'static_cast' : cannot convert from 'IApp *' to 'IApp &'

Below is the generic class and the compiler error occurs in the instance() function.

template<typename DERIVED>
class Singleton
{
public:

    static DERIVED& instance()
    {
        if (!_instance) {
            _instance = new DERIVED;
            std::atexit(_singleton_deleter); // Destruction of instance registered at runtime exit (No leak).
        }

        return static_cast<DERIVED&>(_instance);
    }

protected:

    Singleton() {}
    virtual ~Singleton() {}

private:

    static DERIVED* _instance;

    static void _singleton_deleter() { delete _instance; } //Function that manages the destruction of the instance at the end of the execution.

};

Is it possible to cast this way? I don't want instance() to return a pointer, I'd prefer a reference. Or maybe a weak_ptr? Any ideas how to cast this?

sazr
  • 24,984
  • 66
  • 194
  • 362
  • I would not use a pointer for a singleton. This implementation is not thread safe way too complicated for what you want to achieve. – Guillaume Racicot Dec 23 '15 at 02:22
  • @GuillaumeRacicot Thanks for your comment. What would be more thread safe? Dependency injection? – sazr Dec 23 '15 at 02:25
  • Well... Of course dependency injection is the choice, but when you have to do with singletons, a static local variable is really the best. – Guillaume Racicot Dec 23 '15 at 03:07
  • Here an explanation of this particular use of the static keyword: http://stackoverflow.com/q/6223355/2104697 the only difference in your case is that you want to return a reference to the static variable. – Guillaume Racicot Dec 23 '15 at 03:09

1 Answers1

6

What you are looking for is dereferencing of a pointer, using the indirection operator *. You want either

return static_cast<DERIVED&>(*_instance);
//                         ^^^^^

or

return *static_cast<DERIVED*>(_instance);
//   ^^^^^

or simply:

return *_instance;
//   ^^^^^

since _instance already has type Derived * and the two casts above are no-ops.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084